Push-to-card support

In this document you will learn what steps must be taken to support the "Push-to-card" transfer method in an API integration.

🚧

Qualifications

This guide is only relevant if the following criteria are met:

  • You intend to support the PUSH_TO_CARD transfer method.
  • You are integrating with ReadyRemit via API and not SDK.
  • You have no intention of receiving a PCI DSS Level 4 certification for your product.

Overview

1. Enable a Push-to-Card corridor

The first step to enabling the Push-to-Card transfer method for your users is turn on a Push-to-Card corridor. The ReadyRemit integration team can enable a test corridor for you in the Sandbox environment. Below is an example of a response from the GET /corridors endpoint that includes a Push-to-Card corridor:

curl --location --request GET 'https://sandbox-api.readyremit.com/v1/corridors'  \
--header 'Authorization: Bearer TOKEN' \
--header 'Content-Type: application/json'
[
    {
        "destinationCountry": {
            "name": "United Kingdom",
            "iso3Code": "GBR",
            "iso2Code": "GB"
        },
        "sourceCurrency": [
            {
                "name": "US Dollar",
                "iso3Code": "USD",
                "symbol": "$",
                "decimalPlaces": 2,
                "roundDirection": "STANDARD"
            }
        ],
        "destinationCurrency": [
            {
                "name": "British pound",
                "iso3Code": "GBP",
                "symbol": "£",
                "decimalPlaces": 2,
                "roundDirection": "STANDARD"
            }
        ],
        "transferMethod": "PUSH_TO_CARD"
    }
]

2. The CARD_ID Recipient Account Field

The first 2 steps of the ReadyRemit transfer flow are unchanged for Push-to-Card:

  • Fetch a Quote
  • Create a Recipient

The first change will come when creating a Recipient Account. As in the standard flow, use the Get Recipient Account Fields API endpoint to obtain a list of required fields to create a recipient account for the selected corridor. Below is an example of a response from GET /recipient-account-fields for a Push-to-Card corridor:

curl --location --request GET 'https://sandbox-api.readyremit.com/v1/recipient-account-fields?dstCountryIso3Code=GBR&dstCurrencyIso3Code=GBP&transferMethod=PUSH_TO_CARD&recipientType=PERSON' \
--header 'Authorization: Bearer TOKEN' \
--header 'Content-Type: application/json' 
{
    "fieldSets": [
        {
            "fieldSetId": "CARD_DETAILS",
            "fieldSetName": "Card Details",
            "fields": [
                {
                    "fieldType": "TEXT",
                    "fieldId": "CARD_ID",
                    "name": "Card Id",
                    "isRequired": true,
                    "visibility": "HIDE_AND_REQUIRED",
                    "placeholderText": "Card Id"
                }
            ]
        }
    ]
}

Notice the field returned has a fieldId value of "CARD_ID". The presence of this field is an indication that you will need to kick off the Card Onboarding flow starting in step 4 below.

📘

FAQ

Q: Why is there a different flow for cards?
A: Unlike bank account numbers or other personally identifiable information, collecting a card number from a user falls under the scope of the Payment Card Industry Data Security Standard or PCI DSS. Being PCI DSS certified is required by regulating financial entities and ensures that your user's card information is not compromised. Acquiring a PCI DSS certification is a lengthy, expensive process so in an effort to remove this burden from you, ReadyRemit provides the Card Onboarding flow. The Card Onboarding flow pushes the PCI burden to ReadyRemit and allows you to enable Push-to-Card for your users without going through the process of PCI DSS certification.

3. Create a Card Onboarding Session

curl --location --request POST 'https://sandbox-api.readyremit.com/v1/card-onboarding-sessions' \
--header 'Authorization: Bearer TOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{
    "entityMode": "SENDER",
    "customization": {
        "primaryColor": "#00A000",
        "submitButtonLabel": "NEXT: REVIEW",
        "submitBorderRadius": 40,
        "title": "Deposit via Debit Card",
        "description": "Your refund will be credited directly to your bank account via your Visa or Mastercard debit card.",
        "locale": "en-US",
        "texts": {
            "family": "Arial",
            "size": 14,
            "weight": "500"
        },
        "inputs": {
            "family": "Roboto",
            "size": 18,
            "weight": "500"
        },
        "hints": [
            { "cardHolderName": "Hint for card holder name" },
            { "cardNumber": "Hint for card number" },
            { "expiryDate": "Hint for expiration date" },
            { "cvv2": "Hint for security code" },
            { "addressStreet": "Hint for address" },
            { "zip": "Hint for zip" }
        ]
    }
}'
{
    "id": "20b43f68-73af-4e56-9ec4-c02e0245a377",
    "status":"INCOMPLETE",
    "expirationDate": "2023-02-02T10:48:00.000Z",
    "customization": {
        "primaryColor": "#00A000",
        "submitButtonLabel": "NEXT: REVIEW",
        "submitBorderRadius": 40,
        "title": "Deposit via Debit Card",
        "description": "Your refund will be credited directly to your bank account via your Visa or Mastercard debit card.",
        "locale": "en-US",
        "texts": {
            "family": "Arial",
            "size": 14,
            "weight": "500"
        },
        "inputs": {
            "family": "Roboto",
            "size": 18,
            "weight": "500"
        },
        "hints": [
            { "cardHolderName": "Hint for card holder name" },
            { "cardNumber": "Hint for card number" },
            { "expiryDate": "Hint for expiration date" },
            { "cvv2": "Hint for security code" },
            { "addressStreet": "Hint for address" },
            { "zip": "Hint for zip" }
        ]
    },
    "entityMode": "SENDER",
    "cvv2Required": true,
    "cardNumberRequired": true,
    "cardHolderNameRequired": false,
    "expiryDateRequired": true
    "cardId": null
}

4. Present the Card Onboarding iFrame to the sender

When the Get Recipient Account Fields returns a required CARD_ID field, the Card Onboarding iFrame will need to be presented to the user. This iFrame contains a form for entering card information and should blend in seamlessly to your existing flow. Render the iFrame with an iframe HTML tag and include the id from the Create CardOnbaording Session response as the first URL parameter:

<iframe src="https://sandbox.readyremit.com/AddCard/4b219c89-f739-4400-be40-09cb221f36ae"></iframe>
Card Onboarding iFrame (Desktop)

Card Onboarding iFrame (Desktop)

Card Onboarding iFrame (Mobile)

Card Onboarding iFrame (Mobile)

5. Poll the Get Card Onboarding Session API

The Card Onboarding iFrame removes the burden of PCI DSS compliance by restricting access to the card data fields as the user enters them. This also means that it's more difficult to know when the user has completed the form. The solution to this is to poll the ReadyRemit API for the status of the Card Onboarding Session.

The following API call to GET /card-onboarding-sessions should be made on a 1 second interval. Polling should begin the moment the iFrame is presented to the user and stop when the returned status of the Card Onboarding session is "SUCCEEDED", or "EXPIRED"

Card Onboarding Session Status Flowchart

Card Onboarding Session Status Flowchart

curl --location --request GET 'https://sandbox-api.readyremit.com/v1/card-onboarding-sessions/20b43f68-73af-4e56-9ec4-c02e0245a377' \
--header 'Authorization: Bearer TOKEN' \
{
    "status": "CREATED",
    "id": "20b43f68-73af-4e56-9ec4-c02e0245a377",
    "expirationDate": "2023-03-07T19:11:16.212581Z",
    "cardId": "cfbfc2df-4fa6-45ae-9d85-5e8121040d62",
    "customization": {
        "primaryColor": "#00A000",
        "submitButtonLabel": "NEXT: REVIEW",
        "submitBorderRadius": 40,
        "title": "Deposit via Debit Card",
        "description": "Your refund will be credited directly to your bank account via your Visa or Mastercard debit card.",
        "locale": "en-US",
        "texts": {
            "family": "Arial",
            "size": 14,
            "weight": "500"
        },
        "inputs": {
            "family": "Roboto",
            "size": 18,
            "weight": "500"
        },
        "hints": [
            { "cardHolderName": "Hint for card holder name" },
            { "cardNumber": "Hint for card number" },
            { "expiryDate": "Hint for expiration date" },
            { "cvv2": "Hint for security code" },
            { "addressStreet": "Hint for address" },
            { "zip": "Hint for zip" }
        ]
    },
    "entityMode": "SENDER",
    "cvv2Required": true,
    "cardNumberRequired": true,
    "cardHolderNameRequired": false,
    "expiryDateRequired": true
}

6. Populate the CARD_ID value

Once the Card Onboarding Session has achieved a SUCCESS status, the status polling can stop and we are ready to complete the creation of the Recipient Account. The cardId value should be retrieved from the response body of the Get Card Onboarding Session call and used to populate the value of the CARD_ID field to create the Recipient Account.

curl --location --request POST 'https://sandbox-api.readyremit.com/v1/recipients/RECIPIENT_ID/accounts' \
--header 'Authorization: Bearer TOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{
    "dstCountryIso3Code": "GBR",
    "dstCurrencyIso3Code": "GBP",
    "transferMethod": "PUSH_TO_CARD",
    "fields": [
        {
            "id": "CARD_ID",
            "type": "TEXT",
            "value": "bb58e751-95a1-44e9-a963-78a165217925"
        }
    ]
}'
{
    "recipientAccountId": "0019beac-63d6-4529-917b-5db1cb07dc2a",
    "accountNumber": "************4553",
    "fields": [
        {
            "id": "CARD_ID",
            "type": "TEXT",
            "value": "bb58e751-95a1-44e9-a963-78a165217925"
        }
    ]
}

Card onboarding is complete! You can now use the created recipient account the same way you would with any other account. Funds sent to this account will be pushed directly to the onboarded card.

Next steps

  • To provide your users with the most accurate quote for Push-to-Card, a new quote should be presented to the user with the Recipient Account ID included.
  • A transfer can now be made using the recipient account. Be sure to set the transferMethod to PUSH_TO_CARD in the transfer body.