Skip to main content

Documentation

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 PCI-DSS certification can handle personal identifying information for cards. This method is available to merchants who have signed a special agreement with Rapyd.

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

customer-purchase-goods.jpg
  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.

authorize-payment.jpg
  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.

capture-payment.jpg
  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.

The message sequence diagrams below describe how information is exchanged between Rapyd, the merchant, and the card network.

Two-Step Card Payment

payment-with-late-capture---success.svg

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.

Description of Query Parameters

Query Parameter

Description

country

Enter US as the country code.

currency

Enter USD as the currency code.

When your customer pays for the furniture, you request a card authorization for the 115.65 USD (U.S. Dollars) payment.

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

Description of Body 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_debit_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_debit_visa_card.

You ask Rapyd to process the customer's 115.65 USD (U.S. Dollars) payment as a card authorization.

    • Request

      • // Request URL: POST https://sandboxapi.rapyd.net/v1/payments
        
        // Message body: 
        {
                "amount": 115.65,
                "currency": "USD",
                "payment_method": {
                        "type": "us_debit_visa_card",
                        "fields": {
                                "number": "4111111111111111",
                                "expiration_month": "10",
                                "expiration_year": "25",
                                "cvv": "123",
                                "name": "Test User"
                        }
                },
                "ewallet": "ewallet_8915a7fdeff7be5b7c1a7fa5f0b81414",
                "capture": false
        }
    • .NET Core

      • 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);
                    }
                }
            }
        }
    • JavaScript

      • 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

      • <?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";
        }
        ?>
    • Python

      • 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)

Let's take a look at the response.

    • 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_debit_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.

  • 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.

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:

Description of Path 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.

Description of Body Parameters

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.

You ask Rapyd to capture all of your customer's 115.65 USD (U.S. Dollars) payment.

    • Request

      • // Request URL: POST https://sandboxapi.rapyd.net/v1/payments/payment_fc109dbe553a223401d86156e3adea8c/capture
        
        // Message body: 
        {
           "amount": 115.65
        }
    • .NET Core

      • 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);
                    }
                }
            }
        }
    • JavaScript

      • 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

      • <?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";
        }
        ?>
    • Python

      • 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)

Let's take a look at the response.

    • 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_debit_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.