# Payments - Collections *If you haven’t already, [Sign Up for Sandbox Access](https://rail.io/contact) 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.](/guides/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:** ```bash 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}:` ```javascript { "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](/guides/authentication). ### 2. Create Counterparty First, [Create a Counterparty](/api-docs/openapi/rail-spec#operation/createCounterparty) 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 on Counterparty Types Other counterparty types can be used here, however `BASIC` requires the least information. **πŸ“€ Request:** ```bash 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 destination_counterparty_id in the Create Payment step. ```bash { "data": { "id": "9843d07c-1e52-463e-a7d1-f35f40971025" } } ``` ### 3. Create Payment Once your counterparty is created and is in an ACTIVE status, use [Create Payment](/api-docs/openapi/rail-spec#operation/createPayments). 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:** ```bash 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. ```bash { "data": { "payment_id": "2ce4d1ca-6835-4a06-90b8-22043f4b888f", "status": "REQUESTED" } } ``` ### 3. Review Payment Before accepting a payment you should [Retreive Payment Status](/api-docs/openapi/rail-spec#operation/createPayments). The response will inform you if there are any pending RFIs requiring attention before the payment can be accepted. **πŸ“€ Request:** ```bash 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. ```bash { "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](/api-docs/openapi/rail-spec#operation/acceptPayments) 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:** ```bash 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. ```bash { "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 on Transaction Types `transaction_type` = `PAYMENT_IN`, `category_type` = `PAYMENT`, `category_id` = `{payment_id}`. ```bash { "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-docs/openapi/rail-spec#operation/createCounterparty) - API Spec - Create Payment - [link.](/api-docs/openapi/rail-spec#operation/createPayment) - API Spec - Retrieve Payment Status - [link.](/api-docs/openapi/rail-spec#operation/getPaymentStatus) - API Spec - Accept Payment - [link.](/api-docs/openapi/rail-spec#operation/acceptPayment) - API Spec - Create Subscription - [link.](/api-docs/openapi/rail-spec#operation/createSubscription) **Webhooks:** - Counterparty Webhooks - [link.](/guides/subscriptions_events#counterparty) - Payment Webhooks - [link.](/guides/subscriptions_events#payment) - Transaction Webhooks - [link.](/guides/subscriptions_events#transaction) **Validation:** - Counterparty Types - Required enums to use when creating a counterparty - [link.](/guides/counterparty_types) - Counterparty Validation - Required info to create a counterparty - [link.](/guides/counterparty_validation)