Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/theresasogunle/Fintech-flutterwave-Java-Library/llms.txt

Use this file to discover all available pages before exploring further.

The PreAuthorization class allows you to hold funds on a customer’s card without immediately charging it. This is useful for scenarios like hotel reservations, car rentals, or any situation where you need to guarantee payment availability before providing services.

Overview

Pre-authorization follows a three-step flow:
1

Pre-authorize

Hold funds on the customer’s card without charging
2

Capture

Charge the held amount when ready (e.g., after service delivery)
3

Refund or Void

Release the hold or refund if needed
Pre-authorization is not available for all accounts. This feature requires special approval from Flutterwave. Contact Flutterwave support to enable pre-authorization for your merchant account.

Special Configuration

Pre-authorization requires special API keys:
RaveConstant.PUBLIC_KEY = "FLWPUBK-8cd258c49f38e05292e5472b2b15906e-X";
RaveConstant.SECRET_KEY = "FLWSECK-c51891678d48c39eff3701ff686bdb69-X";
RaveConstant.ENVIRONMENT = Environment.STAGING; // or Environment.LIVE
The keys shown above are special pre-authorization keys. You must use these specific keys for pre-auth transactions, not your regular API keys.

Pre-authorization Parameters

cardno
string
required
Customer’s card number
cvv
string
required
Card CVV/CVC code
expirymonth
string
required
Card expiry month (e.g., “08”)
expiryyear
string
required
Card expiry year (e.g., “20”)
amount
string
required
Amount to pre-authorize
email
string
required
Customer’s email address
phonenumber
string
required
Customer’s phone number
firstname
string
required
Customer’s first name
lastname
string
required
Customer’s last name
txRef
string
required
Your unique transaction reference
charge_type
string
required
Must be set to “preauth”
redirect_url
string
required
URL to redirect after authorization
currency
string
default:"NGN"
Currency code (defaults to NGN)
country
string
default:"NG"
Country code (defaults to NG)
IP
string
Customer’s IP address (auto-detected if not provided)
device_fingerprint
string
Device fingerprint for fraud detection

Pre-authorizing a Card

import com.github.theresasogunle.*;
import org.json.JSONObject;

public class PreAuthExample {
    public static void main(String[] args) throws Exception {
        // Configure special pre-auth keys
        RaveConstant.PUBLIC_KEY = "FLWPUBK-8cd258c49f38e05292e5472b2b15906e-X";
        RaveConstant.SECRET_KEY = "FLWSECK-c51891678d48c39eff3701ff686bdb69-X";
        RaveConstant.ENVIRONMENT = Environment.STAGING;
        
        PreAuthorization ch = new PreAuthorization();
        ch.setCardno("5438898014560229")
            .setCharge_type("preauth")
            .setCvv("812")
            .setExpirymonth("08")
            .setExpiryyear("20")
            .setCurrency("NGN")
            .setCountry("NG")
            .setAmount("100")
            .setEmail("user@example.com")
            .setPhonenumber("08056552980")
            .setFirstname("John")
            .setLastname("Doe")
            .setIP("40.198.14")
            .setTxRef("MXX-ASC-4578")
            .setRedirect_url("https://rave-web.herokuapp.com/receivepayment")
            .setDevice_fingerprint("69e6b7f0b72037aa8428b70fbe03986c");
        
        JSONObject response = ch.preAuthorizeCard();
        System.out.println(response);
        
        // Extract flwRef from response for later use
        String flwRef = response.getJSONObject("data").getString("flwRef");
        System.out.println("Pre-auth Reference: " + flwRef);
    }
}
The charge_type parameter must be set to "preauth" for pre-authorization transactions. The system will hold the specified amount on the card without actually charging it.

Capturing Pre-authorized Funds

Once you’re ready to charge the customer (e.g., after service delivery), capture the pre-authorized amount:
PreAuthorization ch = new PreAuthorization();
ch.setFlwref("FLW-MOCK-d310263f5f73e51d01e6dab32c893679");

JSONObject capture = ch.capture();
System.out.println("Capture Response: " + capture);

if (capture.getString("status").equals("success")) {
    System.out.println("Funds captured successfully!");
}
flwRef
string
required
The payment gateway’s unique reference returned from preAuthorizeCard()

Refunding or Voiding

You can either refund a captured amount or void an uncaptured pre-authorization:

Voiding a Pre-authorization

To release the hold without charging:
PreAuthorization ch = new PreAuthorization();
ch.setFlwref("FLW-MOCK-d310263f5f73e51d01e6dab32c893679")
    .setAction("void");

JSONObject result = ch.refundOrVoid();
System.out.println("Void Response: " + result);

Refunding a Captured Amount

To refund after capturing:
PreAuthorization ch = new PreAuthorization();
ch.setFlwref("FLW-MOCK-d310263f5f73e51d01e6dab32c893679")
    .setAction("refund");

JSONObject result = ch.refundOrVoid();
System.out.println("Refund Response: " + result);
action
string
required
Action to take: either “refund” or “void”
When to use: Before capturing fundsEffect: Releases the hold on customer’s card without any chargeUse case: Customer cancels reservation before check-in

Complete Workflow Example

import com.github.theresasogunle.*;
import org.json.JSONObject;

public class CompletePreAuthFlow {
    public static void main(String[] args) throws Exception {
        // Step 1: Configure
        RaveConstant.PUBLIC_KEY = "FLWPUBK-8cd258c49f38e05292e5472b2b15906e-X";
        RaveConstant.SECRET_KEY = "FLWSECK-c51891678d48c39eff3701ff686bdb69-X";
        RaveConstant.ENVIRONMENT = Environment.STAGING;
        
        PreAuthorization preAuth = new PreAuthorization();
        
        // Step 2: Pre-authorize card
        preAuth.setCardno("5438898014560229")
            .setCharge_type("preauth")
            .setCvv("812")
            .setExpirymonth("08")
            .setExpiryyear("20")
            .setCurrency("NGN")
            .setCountry("NG")
            .setAmount("100")
            .setEmail("user@example.com")
            .setPhonenumber("08056552980")
            .setFirstname("John")
            .setLastname("Doe")
            .setIP("40.198.14")
            .setTxRef("MXX-ASC-4578")
            .setRedirect_url("https://yourdomain.com/callback")
            .setDevice_fingerprint("69e6b7f0b72037aa8428b70fbe03986c");
        
        JSONObject preAuthResponse = preAuth.preAuthorizeCard();
        String flwRef = preAuthResponse.getJSONObject("data").getString("flwRef");
        System.out.println("Pre-authorization successful. FlwRef: " + flwRef);
        
        // Step 3a: Capture funds (when ready to charge)
        preAuth.setFlwref(flwRef);
        JSONObject captureResponse = preAuth.capture();
        
        if (captureResponse.getString("status").equals("success")) {
            System.out.println("Funds captured successfully!");
            
            // Step 4 (optional): Refund if needed
            preAuth.setAction("refund");
            JSONObject refundResponse = preAuth.refundOrVoid();
            System.out.println("Refund status: " + refundResponse.getString("status"));
        }
        
        // OR Step 3b: Void pre-authorization (if not capturing)
        // preAuth.setFlwref(flwRef)
        //     .setAction("void");
        // JSONObject voidResponse = preAuth.refundOrVoid();
        // System.out.println("Void status: " + voidResponse.getString("status"));
    }
}

Use Cases

Hotel Reservations

Hold funds when customer books a room, capture on check-in, void if cancelled

Car Rentals

Pre-authorize for rental amount + deposit, capture actual charges after return

Event Tickets

Hold payment when tickets are reserved, capture closer to event date

Custom Orders

Hold funds during production, capture when item ships

Method Reference

MethodParametersReturnsDescription
preAuthorizeCard()Card details + charge_type: "preauth"JSONObjectHolds funds on card without charging
capture()flwRefJSONObjectCaptures pre-authorized funds
refundOrVoid()flwRef, actionJSONObjectRefunds or voids pre-authorization

Important Considerations

  • Pre-authorizations typically expire after 7-30 days (varies by card issuer)
  • Capture funds before the pre-auth expires
  • Check with card networks for specific time limits
  • Don’t hold funds longer than necessary

Best Practices

  1. Communicate clearly with customers: Let them know funds are being held, not charged immediately
  2. Set expectations: Inform customers when the hold will be released if not captured
  3. Capture promptly: Don’t wait until the last minute before pre-auth expiration
  4. Handle expirations: Implement logic to detect and handle expired pre-authorizations
  5. Void unused pre-auths: Release holds as soon as you know they won’t be needed
  6. Monitor transactions: Track pre-auth status and follow up on pending captures

Troubleshooting

Pre-authorization Failed

  • Verify you’re using the special pre-auth API keys
  • Ensure charge_type is set to "preauth"
  • Check that pre-authorization is enabled for your account
  • Verify card details are correct

Capture Failed

  • Check if pre-authorization has expired
  • Verify the flwRef matches the original pre-auth
  • Ensure the amount doesn’t exceed pre-authorized amount
  • Confirm funds are still available on the card

Void/Refund Failed

  • Verify the correct action (“void” vs “refund”) for the transaction state
  • Check if transaction has already been captured (use refund, not void)
  • Ensure the flwRef is valid and matches the transaction

Next Steps

Card Payments

Learn about standard card payment processing

Transaction Verification

Verify and track transaction status

Build docs developers (and LLMs) love