Two-Step Payment

Authorize a card and capture funds after the order is completed.

You may prefer getting a card authorization while the customer's order on your website is being assembled, or processed. Two-Step Payment first authorizes the card, and when the order is shipped, you ask Rapyd to capture the payment.

🚧

PCI Certification

Only clients with PCIPCI - Payment Card Industry certification can handle personal identifying information for cards.

Card Authorization and Capture Workflow

Finding the specific payment methods you'll accept and the corresponding required fields that customers fill out is described under How it Works.

Step 1 - Customer Purchases Goods

  1. Using your website or app, a customer adds furniture to the shopping cart and checks out.
  2. Your website displays available payment methods.
  3. The customer selects 'card'.
  4. Your website requests card details.
  5. The customer provides the details and clicks Pay Now.

Step 2 - Authorizing the Card Payment

  1. Your website back end asks Rapyd for card authorization.
  2. Rapyd processes the authorization request and returns a confirmation and payment ID.
  3. You notify the customer that the purchase succeeded.

Step 3 - Capturing the Card Payment

  1. You prepare and pack your product for delivery.
  2. Your website back end asks Rapyd to capture the payment, specifying the Payment ID.
  3. Rapyd processes the capture request and returns the updated transaction status.

How It Works

Find Available Payment Methods

Decide which payment methods you will accept, so that your customer can specify their payment methods on your payment page. Use List Payment Methods by Country. with the following parameters:

  • US and USD is displayed as an example for country and currency.

Query Parameter

Description

country

Enter US as the country code.

currency

Enter USD as the currency code.

Find Required Fields for the Payment Method

Create a Wallet

Requesting Payment Authorization

When your customer pays for the furniture, you request a card authorization for the $112.50 payment.

For that, you'll use Create Payment with the following parameters:

Body Parameter

Description

amount

Enter 115.65 as the payment amount.

currency

Enter USD as the currency code.

capture

Enter false as the value. This tells Rapyd to create only a card authorization. The authorized payment will be captured at a later time.

ewallet

Enter the wallet 'id' that you received when you created Four Star Furniture's company wallet in your sandbox. For purposes of this use case lesson, we are using ewallet_8915a7fdeff7be5b7c1a7fa5f0b81414, which is the wallet ID we created in our sandbox.

payment_method

Enter a 'payment_method' object with the following fields:
type - Enter the payment method type you want to use for your test. For purposes of this use case lesson, we are using us_visa_card.
fields - Enter an object that contains all required fields, as shown in the response when you ran Get Payment Method Required Fields. For purposes of this use case lesson, we are using the fields required for us_visa_card.

Create Payment request

You ask Rapyd to process the customer's $112.50 payment as a card authorization.

// Request URL: POST https://sandboxapi.rapyd.net/v1/payments

// Message body: 
{
    "amount": 115.65,
    "currency": "USD",
    "payment_method": {
        "type": "us_visa_card",
        "fields": {
            "number": "4111111111111111",
            "expiration_month": "10",
            "expiration_year": "25",
            "cvv": "123",
            "name": "Test User"
        }
    },
    "ewallet": "ewallet_8915a7fdeff7be5b7c1a7fa5f0b81414",
    "capture": false
}
using System;
using System.Text.Json;

namespace RapydApiRequestSample
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var requestObj = new
                {
                    amount = 115.65,
                    capture = false,
                    currency = "USD",
                    ewallet = "ewallet_8915a7fdeff7be5b7c1a7fa5f0b81414",
                    payment_method = new
                    {
                        type = "us_visa_card",
                        fields = new
                        {
                            number = "4111111111111111",
                            expiration_month = "10",
                            expiration_year = "25",
                            cvv = "123",
                            name = "John Doe",
                        }
                    },
                };

                string request = JsonSerializer.Serialize(requestObj);

                string result = RapydApiRequestSample.Utilities.MakeRequest("POST", "/v1/payments", request);

                Console.WriteLine(result);
            }
            catch (Exception e)
            {
                Console.WriteLine("Error completing request: " + e.Message);
            }
        }
    }
}
const makeRequest = require('<path-to-your-utility-file>/utilities').makeRequest;

async function main() {
  try {
    const body = {
      amount: 115.65,
      currency: 'USD',
      payment_method: {
        type: 'us_visa_card',
        fields: {
          number: '4111111111111111',
          expiration_month: '10',
          expiration_year: '20',
          cvv: '123',
          name: 'John Doe'
        }
      },
      ewallet: 'ewallet_8915a7fdeff7be5b7c1a7fa5f0b81414',
      capture: false
    };
    const result = await makeRequest('POST', '/v1/payments', body);

    console.log(result);
  } catch (error) {
    console.error('Error completing request', error);
  }
}
<?php
$path = $_SERVER['DOCUMENT_ROOT'];
$path .= "/<path-to-your-utility-file>/utilities.php";
include($path);

$body = [
    "amount" => "115.65",
    "currency" => "USD",
    "ewallet" => "ewallet_8915a7fdeff7be5b7c1a7fa5f0b81414",
    "payment_method" => [
        "type" => "us_visa_card"
    ]
];

try {
    $object = make_request('post', '/v1/payments', $body);
    var_dump($object);
} catch (Exception $e) {
    echo "Error: $e";
}
?>
from pprint import pprint

from utilities import make_request

payment_body = {
    "amount": 115.65,
    "currency": "USD",
    "payment_method": {
        "type": "us_visa_card",
        "fields": {
            "number": "4111111111111111",
            "expiration_month": "10",
            "expiration_year": "25",
            "cvv": "123",
            "name": "John Doe"
        }
    },
    "ewallet": "ewallet_452c8cd682f347b4abee9bbee04eac03",
    "capture": False
}

create_payment_response = make_request(method='post',
                                       path='/v1/payments',
                                       body=payment_body)
pprint(create_payment_response)

Create Payment response

Let's take a look at the response. Payment Object describes the fields in the response.

{
    "status": {
        "error_code": "",
        "status": "SUCCESS",
        "message": "",
        "response_code": "",
        "operation_id": "7b0f7ce9-ed39-4eb5-ae1d-4210ad865072"
    },
    "data": {
        "id": "payment_fc109dbe553a223401d86156e3adea8c",
        "amount": 0,
        "original_amount": 115.65,
        "is_partial": false,
        "currency_code": "USD",
        "country_code": "us",
        "status": "ACT",
        "description": "",
        "merchant_reference_id": "",
        "customer_token": "cus_bd1338e2b5980deb6e3eae9eb785fdce",
        "payment_method": "card_164f3fd242091eba09f4b8c1f4a75597",
        "expiration": 0,
        "captured": false,

 //     ...         

        "paid": false,
        "paid_at": 0,

 //     ...         

        "ewallet_id": "ewallet_8915a7fdeff7be5b7c1a7fa5f0b81414",
        "ewallets": [
            {
                "ewallet_id": "ewallet_8915a7fdeff7be5b7c1a7fa5f0b81414",
                "amount": 115.65,
                "percent": 100,
                "refunded_amount": 0
            }
        ],
        "payment_method_options": {},
        "payment_method_type": "us_visa_card",
        "payment_method_type_category": "card",

 //     ...         

    }
}

The data section of this response shows:

  • The payment id is payment_fc109dbe553a223401d86156e3adea8c. When you run this example in your own sandbox, you will get a different ID, which you will need for a later step in this use case.
  • amount is 0, which indicates that no money has actually been received yet.
  • original_amount is 115.65
  • currency_code is USD
  • The status is ACT (active). This indicates that the payment has not yet been captured. Payment Object lists possible values for status.
  • The customer_token is cus_bd1338e2b5980deb6e3eae9eb785fdce, which is a unique customer ID for this transaction only. Since the request did not specify an existing customer saved in the system, the customer is treated as a guest customer.
  • The payment_method is a unique payment method ID for this transaction only.
  • captured is false because this is a card authorization only.

Capturing the Payment

You have prepared and packed your sold order. Before you ship it, you want to capture the card payment that was authorized previously.

For that, you'll use Capture Payment with the following parameters:

Path Parameter

Description

payment

Enter the payment 'id' that you received when you created the payment in your sandbox. For purposes of this use case lesson, we are using payment_fc109dbe553a223401d86156e3adea8c, which is the payment ID we created in our sandbox.

Body Parameter

Description

amount

Enter 115.65 as the payment amount.

Because you are capturing the whole amount that was previously authorized, the amount parameter is optional.

Capture Payment request

You ask Rapyd to capture all of your customer's $115.65 payment.

// Request URL: POST https://sandboxapi.rapyd.net/v1/payments/payment_fc109dbe553a223401d86156e3adea8c/capture

// Message body: 
{
   "amount": 115.65
}
using System;
using System.Text.Json;

namespace RapydApiRequestSample
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                string payment = "payment_9d59d89e3ce3519647f0d22f5d37e23c";

                var requestObj = new
                {
                    amount = 115.65,
                };

                string request = JsonSerializer.Serialize(requestObj);

                string result = RapydApiRequestSample.Utilities.MakeRequest("POST", $"/v1/payments/{payment}/capture", request);

                Console.WriteLine(result);
            }
            catch (Exception e)
            {
                Console.WriteLine("Error completing request: " + e.Message);
            }
        }
    }
}
const makeRequest = require('<path-to-your-utility-file>/utilities').makeRequest;

async function main() {
  try {
    const body = {
      amount: 115.65
    };
    const result = await makeRequest(
      'POST',
      '/v1/payments/payment_fc109dbe553a223401d86156e3adea8c/capture',
      body
    );

    console.log(result);
  } catch (error) {
    console.error('Error completing request', error);
  }
}
<?php
$path = $_SERVER['DOCUMENT_ROOT'];
$path .= "/<path-to-your-utility-file>/utilities.php";
include($path);

try {
    $capturePayment = make_request('post', '/v1/payments/payment_fc109dbe553a223401d86156e3adea8c');
    var_dump($capturePayment);
} catch (Exception $e) {
    echo "Error: $e";
}
?>
from pprint import pprint

from utilities import make_request

capture_payment_body = {
    "amount": 115.65
}
capture_payment_response = make_request(method='post',
                                        path='/v1/payments/payment_fc109dbe553a223401d86156e3adea8c/capture',
                                        body=capture_payment_body)

pprint(capture_payment_response)

Capture Payment response

Let's take a look at the response. Payment Object describes the fields in the response.

{
    "status": {
        "error_code": "",
        "status": "SUCCESS",
        "message": "",
        "response_code": "",
        "operation_id": "8053816d-3d99-47cd-a216-ccc35e38ccce"
    },
    "data": {
        "id": "payment_fc109dbe553a223401d86156e3adea8c",
        "amount": 115.65,
        "original_amount": 115.65,
        "is_partial": false,
        "currency_code": "USD",
        "country_code": "us",
        "status": "CLO",
        "description": "",
        "merchant_reference_id": "",
        "customer_token": "cus_bd1338e2b5980deb6e3eae9eb785fdce",
        "payment_method": "card_164f3fd242091eba09f4b8c1f4a75597",
        "expiration": 0,
        "captured": true,

 //     ...         

        "paid": true,
        "paid_at": 1590485097,

 //     ...         

        "ewallet_id": "ewallet_8915a7fdeff7be5b7c1a7fa5f0b81414",
        "ewallets": [
            {
                "ewallet_id": "ewallet_8915a7fdeff7be5b7c1a7fa5f0b81414",
                "amount": 115.65,
                "percent": 100,
                "refunded_amount": 0
            }
        ],
        "payment_method_options": {},
        "payment_method_type": "us_visa_card",
        "payment_method_type_category": "card",

 //     ...         

    }
}

The data section of this response shows that the status has changed to CLO (closed) and the amount has changed to the full amount of the purchase. Payment Object lists possible values for status.

📘

Looking for more in-depth technical information?

Want to see the Rapyd API methods and objects that you'll use?
Visit the Rapyd API Reference Documentation for more technical details.


Updated about a month ago


What's Next

Payment with FX

Two-Step Payment


Authorize a card and capture funds after the order is completed.

Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.