Menu

Payment Authorization and Capture

This guide provides an overview of how to authorize and then capture a card payment.


Authorizing a card payment allows you to ring-fence funds in a customer's bank account, days or even weeks before the actual payment occurs – for example when making hotel reservations or booking car rentals. Note that authorizations cannot be used with PayPal orders.

For information about which payment options you can combine with an authorized payment, please checkhere.

To be able to authorize a payment, you need to enable Authorizations viaOrder Settings.

At this stage, you need to have collected the customer’s card details securely using one of the methods above.

Payment authorization is a two stage process:

  1. Authorizing the payment
  2. Capturing the payment – this is when the money is actually taken from the shopper’s account

Stage 1: Authorizing a Payment

When you authorize a payment, you are effectively ring-fencing funds in your customer’s bank account.

When setting up an authorized payment the only additional process additional to taking a standard payment is indicating it is an authorizeOnly order. You can also authorize an order while using 3D Secure.

The code example below show you how to do this.

Copied!
curl https://api.worldpay.com/v1/orders
-H "Authorization:your-test-service-key"
-H "Content-type: application/json"
-X POST
-d '{
    "token" : "your-order-token",
    "orderDescription" : "Order description",
    "amount" : 500,
    "currencyCode" : “GBP",
    "authorizeOnly" : true}'

The response to this call will include the following JSON object:

{
    "orderCode" : "worldpay-generated-order-code",
    "token" : "your-order-token",
    "orderDescription" : "Order description",
    "authorizedAmount" : 500,
    "currencyCode" : "GBP",
    "authorizeOnly" : true,
    "paymentStatus":"AUTHORIZED",
    "paymentResponse" : 
    {
        "type" : "ObfuscatedCard",
        "name" : "John Smith",
        "expiryMonth" : "7",
        "expiryYear" : "2018",
        "cardType" : "VISA",
        "maskedCardNumber" : "**** **** **** 1111" },
        "environment" : "TEST"
}
$worldpay = new Worldpay('your-test-service-key');

$billing_address = array(
    "address1"=>'123 House Road',
    "address2"=> 'A village',
    "address3"=> '',
    "postalCode"=> 'EC1 1AA',
    "city"=> 'London',
    "state"=> '',
    "countryCode"=> 'GB',
);

try {
    $response = $worldpay->createOrder(array(
        'token' => 'your-order-token',
        'amount-in-cents' => 500,
        'currencyCode' => 'GBP',
        'name' => 'test name',
        'billingAddress' => $billing_address,
        'orderDescription' => 'Order description',
        'customerOrderCode' => 'Order code',
        'authoriseOnly' => true
    ));
    if ($response['paymentStatus'] === 'AUTHORIZED') {
        $worldpayOrderCode = $response['orderCode'];
    } else {
        throw new WorldpayException(print_r($response, true));
    }
} catch (WorldpayException $e) {
    echo 'Error code: ' . $e->getCustomCode() . '
    HTTP status code:' . $e->getHttpStatusCode() . '
    Error description: ' . $e->getDescription()  . ' 
    Error message: ' . $e->getMessage();
} catch (Exception $e) { 
    echo 'Error message: '. $e->getMessage();
}
worldpay = Worldpay.new('your-test-service-key')

begin

    billingAddress = {
        "address1"=>'123 House Road',
        "address2"=> 'A village',
        "address3"=> '',
        "postalCode"=> 'EC1 1AA',
        "city"=> 'London',
        "state"=> '',
        "countryCode"=> 'GB'
    }

    response = worldpay.createOrder({
        'token' => 'your-order-token',
        'amount' => 500,
        'currencyCode' => 'GBP',
        'name' => 'test name',
        'authoriseOnly' =>  true,
        'billingAddress' => billingAddress,
        'orderDescription' => 'Order description',
        'customerOrderCode' => 'Order code'
    })

    if (response['body']['paymentStatus'] === 'SUCCESS')
        @_worldpayOrderCode = response['body']['orderCode']
    else
        raise response.to_s
    end
rescue Exception => e
    print e.to_s
end
WorldpayRestClient restClient = new WorldpayRestClient("https://api.worldpay.com/v1", "your-test-service-key");

var address = new Address()
{
    address1 = "123 House Road",
    address2 = "A village",
    city = "London",
    countryCode = CountryCode.GB,
    postalCode = "EC1 1AA"
};

var orderRequest = new OrderRequest()
{
    token = "your-token",
    amount = 500,
    currencyCode = CurrencyCode.GBP,
    name = "test name",
    orderDescription = "Order description",
    customerOrderCode = "Order code",
    authorizeOnly = true
};

orderRequest.billingAddress = address;

try
{
    OrderResponse orderResponse = restClient.GetOrderService().Create(orderRequest);

    string orderCode;
    if (orderResponse.paymentStatus == OrderStatus.AUTHORIZED)
    {
        orderCode = orderResponse.orderCode;
    }
    else
    {
        throw new WorldpayException("Expected order status AUTHORIZED");
    }
}
catch (WorldpayException e)
{
    Console.WriteLine("Error code:" + e.apiError.customCode);
    Console.WriteLine("Error description: " + e.apiError.description);
    Console.WriteLine("Error message: " + e.apiError.message);
}
WorldpayRestClient restClient = new WorldpayRestClient("your-test-service-key");

OrderRequest orderRequest = new OrderRequest();
orderRequest.setAuthoriseOnly(true);
orderRequest.setToken("your-order-token");
orderRequest.setAmount(500);
orderRequest.setCurrencyCode(CurrencyCode.GBP);
orderRequest.setName("test name");
orderRequest.setOrderDescription("Order description");
orderRequest.setCustomerOrderCode("Order code");

Address address = new Address();
address.setAddress1("123 House Road");
address.setAddress2("A village");
address.setCity("London");
address.setCountryCode(CountryCode.GB);
address.setPostalCode("EC1 1AA");
orderRequest.setBillingAddress(address);

try {
    OrderResponse orderResponse = restClient.getOrderService().create(orderRequest);
    System.out.println("Order code: " + orderResponse.getOrderCode());
} catch (WorldpayException e) {
    System.out.println("Error code: " + e.getApiError().getCustomCode());
    System.out.println("Error description: " + e.getApiError().getDescription());
    System.out.println("Error message: " + e.getApiError().getMessage());
}

When the authorization has been successfully completed, you will see in the response that the paymentStatus shows as AUTHORIZED. A full list of payment states is described in theAPI Reference.

Stage 2: Capturing a Payment

In order to complete the payment process, you must capture the authorized order.

You cannot capture an amount higher than the amount originally authorized, and can only capture once, even if the amount captured is less than that originally authorized. If you wish to capture any additional amount beyond that authorized, you will need to make a new order.

Funds must be captured within a 5 - 11 day period, depending on the rules of the card provider. To capture an order you must submit the Order Code and optionally the amount to be captured.

The code example below shows you how to do this:

Copied!
curl https://api.worldpay.com/v1/orders/[your order code]/capture
-H "Authorization:your-test-service-key"
-H "Content-type: application/json"
-X POST
-d '{"captureAmount" : 500}'

The response to this call will include the following JSON object:

{
    "orderCode" : "worldpay-generated-order-code",
    "token" : "your-order-token",
    "orderDescription" : "your-order-description",
    "authorizedAmount" : 500,
    "amount" : 500,
    "currencyCode" : "GBP",
    "authorizeOnly" : true,
    "paymentStatus" : "SUCCESS",
    "paymentResponse" : 
    {
        "type" : "ObfuscatedCard",
        "name" : "John Smith",
        "expiryMonth" : "7",
        "expiryYear" : "2018",
        "cardType" : "VISA",
        "maskedCardNumber" : "**** **** **** 1111" },
        "environment" : "TEST"
}
$worldpay = new Worldpay('your-test-service-key');

try {
    $worldpay->captureAuthorisedOrder('your-order-code','amount-to-capture');
} catch (WorldpayException $e) {
    echo 'Error code: ' . $e->getCustomCode() . '
    HTTP status code:' . $e->getHttpStatusCode() . '
    Error description: ' . $e->getDescription()  . ' 
    Error message: ' . $e->getMessage();
} catch (Exception $e) { 
    echo 'Error message: '. $e->getMessage();
}
worldpay = Worldpay.new('your-service-key')
response = worldpay.captureAuthorisedOrder('order-code', 100);
var client = new WorldpayRestClient(Configuration.ServiceKey);
var amount = Int32.Parse("amount-to-capture");

try {
    var response = client.GetOrderService().CaptureAuthorizedOrder("your-order-code", amount);

    ServerResponse.Text = "Order code:" + response.orderCode +
                          "Payment Status: " + response.paymentStatus +
                          "Environment: " + response.environment;
    SuccessPanel.Visible = true;
}
catch (WorldpayException exc) {
    ErrorControl.DisplayError(exc.apiError);
}
catch (Exception exc) {
    throw new InvalidOperationException("Error sending request ", exc);
}
OrderService orderService = new WorldpayRestClient(yourServiceKey).getOrderService();

CaptureOrderRequest captureOrderRequest = new  CaptureOrderRequest();
captureOrderRequest.setCaptureAmount(yourAmount);

orderService.capture(captureOrderRequest, yourOrderCode);

When the payment has been processed you will see in the response that the paymentStatus is marked as SUCCESS. A full list of payment statuses are described in theAPI Reference.

You have now successfully completed your first authorized payment!

Authorization cancellation and expiry

Authorizations can be cancelled prior to the payment being captured if the payment is no longer needed. How you do this is described below. Typically, Authorizations will expire after about 5 - 11 days, depending on the rules of the card provider. Our webhooks will notify you when an authorization expires.

Cancelling an Authorization

You can cancel an authorization by deleting the order. If this is successful, the order will show the status CANCELLED.

Copied!
curl https://api.worldpay.com/v1/orders/[your order code]
-H "Authorization:your-test-service-key"
-H "Content-type: application/json"
-X DELETE
$worldpay = new Worldpay('your-test-service-key');

try {
    $worldpay->cancelAuthorisedOrder('your-order-code');
} catch (WorldpayException $e) {
    echo 'Error code: ' . $e->getCustomCode() . '
    HTTP status code:' . $e->getHttpStatusCode() . '
    Error description: ' . $e->getDescription()  . ' 
    Error message: ' . $e->getMessage();
} catch (Exception $e) { 
    echo 'Error message: '. $e->getMessage();
}
worldpay = Worldpay.new("your-service-key") worldpay.cancelAuthorisedOrder(orderCode);
var client = new WorldpayRestClient(Configuration.ServiceKey);

try {
    client.GetOrderService().CancelAuthorizedOrder(orderCode);
    ServerResponse.Text = String.Format("Authorized order {0} has been cancelled", "your-order-code");
    SuccessPanel.Visible = true;
}
catch (WorldpayException exc) {
    ErrorControl.DisplayError(exc.apiError);
}
catch (Exception exc){
    throw new InvalidOperationException("Error sending request ", exc);
}
orderService.cancel(yourOrderCode);
Transaction authorizedResponse = orderService.findOrder(yourOrderCode);

if(!authorizedResponse.getOrderResponse().getPaymentStatus().equals(OrderStatus.CANCELLED.name())){
    throw new WorldpayException("Order was not correctly cancelled");
}

Authorization Expiry

Authorizations that are not captured or cancelled will eventually expire automatically. This releases the authorized funds back to the customer for their immediate use, and a capture can no longer be made. After expiry the order will show the status EXPIRED.

Expiry typically occurs after 5 - 11 days, depending on the card issuer. If payment is still required then you will need to create a new order.

Zero Authorizations

Some businesses need to check payment card validity ahead of time e.g. a hotel takes a booking via a 3rd party website so needs to verify the card details.

Using a 0 amount in the order request, together with authoriseOnly: true, will validate the card details without making a charge to the account. Note that you cannot capture any funds for such an order.

Note: In the case of Amex orders, the minimum order amount is 1 minor unit e.g. £0.01 .

Suggested next steps: