Payments - Collections

If you haven’t already, Sign Up for Sandbox Access to get your client ID and secret to work through this Build Guide!

Use the Rail Payments API to receive payment collections from external counterparties. Receive payments from customers, collect subscriptions from investors, build a payment gateway or a checkout. All of these use cases and more are possible using the below guide.

Prerequisities

  1. Customer onboarded - The corporation or individual wishing to receive the payment has been fully onboarded and is in an ACTIVE status. See Applications.
  2. Account open - The onboarded customer has an account in the asset type they wish the payment to settle in. The account is in an OPEN status.

Steps

1. Authenticating Your Request

Every request you make to a Rail API endpoint requires an AUTH_TOKEN. We secure our endpoints using standards based OAuth2 Client Credentials Grant and scopes. This makes authenticating secure and easy.

To obtain the AUTH_TOKEN , you will need to authorize your account using your BASE_64_ENCODED_CLIENTID_AND_SECRET with the scopes you require:

πŸ“€ Request:

Copy
Copied
curl --location --request POST 'https://auth.layer2financial.com/oauth2/ausbdqlx69rH6OjWd696/v1/token?grant_type=client_credentials&scope=customers:read+customers:write+accounts:read+accounts:write+exchanges:read+exchanges:write' \
--header 'Accept: application/json' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Cache-Control: no-cache' \
--header 'Authorization: Basic {BASE_64_ENCODED_CLIENTID_AND_SECRET}' \

πŸ“₯ Response:
This gives you a response object containing your {AUTH_TOKEN}:

Copy
Copied
{
	"token_type":"Bearer",
	"expires_in":43200,
	"access_token": {AUTH_TOKEN},
	"scope":"customers:read customers:write accounts:write accounts:read exchanges:read exchanges:write"
}

The scopes we’ll need for this tutorial are:

  • customers:read and customers:write so we can create our customer and get information about them.
  • accounts:read and accounts:write so we can create our counterparties and get information about them.
  • payments:read and payments:write so we can create our payments and get information about them.

The full list of scopes are available here.

2. Create Counterparty

First, Create a Counterparty to represent the external corporation or individual who the customer wishes to collect payments from. The relevant counterparty type here is counterparty_type = BASIC.

πŸ“ Note: Other counterparty types can be used here, however BASIC requires the least information.

πŸ“€ Request:

Copy
Copied
curl --location POST 'https://alpha.layer2financial.dev/api/v1/counterparties' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {AUTH_TOKEN}' \
--data '{
  "customer_id": "XYZ_012",
  "counterparty_type": "BASIC",
  "profile": {
        "profile_type": "INDIVIDUAL",
        "name": "Joe Bloggs",
        "address": {
            "state": "MA",
            "country_code": "US"
        },
        "relationship_to_customer": "CUSTOMER"
    }
}'

πŸ“₯ Response:
The response object will contain a unique id for the newly created counterparty. This id will be used as the destinationcounterpartyid in the Create Payment step.

Copy
Copied
{
    "data": {
        "id": "9843d07c-1e52-463e-a7d1-f35f40971025"
    }
}

3. Create Payment

Once your counterparty is created and is in an ACTIVE status, use Create Payment. Set the source_counterparty_id to be the counterparty id retrieved in step 2. Set the account_id to be the account the customer would like funds to settle into.

πŸ“€ Request:

Copy
Copied
curl --location POST 'https://sandbox.layer2financial.dev/api/v1/payments' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {AUTH_TOKEN}' \
--data '{
    "payment_source": {
        "source_counterparty_id": "9843d07c-1e52-463e-a7d1-f35f40971025",
        "asset_type": ["FIAT_TESTNET_USD"]
    },
    "payment_destination": {
        "account_id": "Automation-Account-4724"
    },
    "payment_info": {
        "description": "Invoice 123"
    }
}'

πŸ“₯ Response:
The response object will contain a unique id for the newly created payment.

Copy
Copied
{
    "data": {
        "payment_id": "2ce4d1ca-6835-4a06-90b8-22043f4b888f",
        "status": "REQUESTED"
    }
}

3. Review Payment

Before accepting a payment you should Retreive Payment Status. The response will inform you if there are any pending RFIs requiring attention before the payment can be accepted.

πŸ“€ Request:

Copy
Copied
curl --location GET 'https://sandbox.layer2financial.dev/api/v1/payments/{payment_id}/status' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {AUTH_TOKEN}' \
--data '{
    "payment_source": {
        "source_counterparty_id": "9843d07c-1e52-463e-a7d1-f35f40971025",
        "asset_type": ["FIAT_TESTNET_USD"]
    },
    "payment_destination": {
        "account_id": "Automation-Account-4724"
    },
    "payment_info": {
        "description": "Invoice 123"
    }
}'

πŸ“₯ Response:
The response object will return the current status of the payment. Payments with a status of CHANGES_REQUESTED require action to be taken before the payment can be accepted.

Copy
Copied
{
    "data": {
        "payment_id": "2ce4d1ca-6835-4a06-90b8-22043f4b888f",
        "status": "REQUESTED",
		...
    }
}

4. Accept Payment

βœ… Best Practice - Upload Documents Before Accepting:
Before accepting a payment, upload proof of payments, transaction source of funds and additional context as it will reduce likelihood of RFIs and speed up payment processing.

βœ… Best Practice - Ensure Memos are Used:
Ensuring the counterparty (payor) provides the unique memo when submitting their payment ensures smooth payment reconciliation thus reducing settlement times.

To initiate retrive payment instructions, use Accept Payment using the payment id. The response will return the unique payment instructions to be provided to the counterparty. Each payment instruction is unique ensuring easy reconciliation when the payor sends funds.

πŸ“€ Request:

Copy
Copied
curl --location POST 'https://sandbox.layer2financial.dev/api/v1/payments/{payment_id}/accept' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {AUTH_TOKEN}' \
--data '{
    "payment_source": {
        "source_counterparty_id": "9843d07c-1e52-463e-a7d1-f35f40971025",
        "asset_type": ["FIAT_TESTNET_USD"]
    },
    "payment_destination": {
        "account_id": "Automation-Account-4724"
    },
    "payment_info": {
        "description": "Invoice 123"
    }
}'

πŸ“₯ Response:
The response will return provide deposit instructions that are unique to the payment. These instructions are what the counterparty must send the funds to.

Copy
Copied
{
    "data": {
        "payment_id": "2ce4d1ca-6835-4a06-90b8-22043f4b888f",
        "status": "ACCEPTED"
    }
}

5. Receive Payment Transactions

When funds arrive at specified payment instructions, a payment transaction will appear on the relevant account in PENDING status. A TRANSACTION_PENDING webhook is emitted to notify you of this event. Before the funds are made available the transaction must pass the transaction monitoring process.

When the transaction is approved, the transaction status is updated to POSTED, a TRANSACTION_POSTED webhook is sent and the funds are made available to the customer.

Below is what the payment transactions looks like on the account.

πŸ“ Note - transaction_type = PAYMENT_IN, category_type = PAYMENT, category_id = {payment_id}.

Copy
Copied
{
	"id": "string",
	"value": 0,
	"transaction_date": "2019-08-24T14:15:22Z",
	"transaction_posted_date": "2019-08-24T14:15:22Z",
	"transaction_status": "AUTHORIZED",
	"transaction_type": "PAYMENT_IN",
	"category_type": "PAYMENT",
	"category_id": "string",
	"description": "string",
	"originator": {
		"originator_type": "FIAT_US",
		"profile": {
			"name": "string"
		}
	},
	"rail_information": {
		"rail": "string",
		"reference": "string",
		"memo": "string"
	}
}

Useful Information

API Specifications:

  • API Spec - Create Counterparty - link.
  • API Spec - Create Payment - link.
  • API Spec - Retrieve Payment Status - link.
  • API Spec - Accept Payment - link.
  • API Spec - Create Subscription - link.

Webhooks:

  • Counterparty Webhooks - link.
  • Payment Webhooks - link.
  • Transaction Webhooks - link.

Validation:

  • Counterparty Types - Required enums to use when creating a counterparty - link.
  • Counterparty Validation - Required info to create a counterparty - link.
Β© 2024 Rail. All Rights Reserved.