Integrating with the Anchor Platform for facilitating cross-border payments involves implementing the following, at a mimimum:
PUT /customerKYC API endpoints to request & collect customers' KYC data
GET /rateRFQ API endpoint to provide FX rates between the on & off-chain assets supported
GET /transactionsrequests to fetch updates on the Anchor Platform's transactions' statuses (documentation coming soon)
PATCH /transactionsrequests to update the Anchor Platform's transactions' statuses
The following may also be required depending on your use case:
GET /feeif your business wants to provide senders the option to skip the quote creation step
GET /unique_addressif your business uses a custody service for on-chain assets
DELETE /customerif your business wants or is required to allow senders to request deletion of customer data
Create a Business Server
First, lets create a business server and add it to our docker compose file.
Next, create a simple web server using your preferred programming language and a
Dockerfile that starts the server.
docker compose up should successfully start all three services.
This guide does not provide an example implementation of the endpoints, but you can find more information about the request and response schemas in the Anchor Platform API Reference, and the sections below will expand on concepts important to understand when implementing the endpoints.
Customer Callback Endpoints
The Anchor Platform never stores your customers' PII, and instead acts as a proxy server between client applications and your business, forwarding requests and responses to the other party. Currently, requests and responses are almost identical to those defined in the SEP-12 KYC API specification.
Customers can be identified using two approaches.
The first approach uses a Stellar account and memo. When using the Anchor Platform for facilitating cross-border payments, the sending organization uses their own Stellar account, the one used to authenticate via SEP-10 Stellar Authentication, when registering customers with your business. Memos are used to distinguish unique customers originating from the same sending organization.
The second approach uses customer IDs generated by your service. For example, if a sending organization is registering a customer, your business will receive a
PUT /customer request like the following:
In this example, the
GDJ...X47 public key identifies the sending organization, and the
780284017 memo identifies the customer. Memos are usually 64-bit integers, but they can also be other data types, so they should be saved as strings. In response, your business should return a customer ID.
Your business server can use any identifer for customers as long as it is a string.
Following the registration of a customer, the sending organization can use either approach when checking the customer's status. For example, you may get a
GET /customer request like the following:
Or, the sending organziation could use the identifier you returned when they originally registered the customer.
Your business will need to maintain a mapping between the account & memo used to originally register the customer and the ID you return in the response, as well as the KYC data provided. In future iterations of the Anchor Platform, we may maintain this mapping for your business so you only have to work with the IDs you generate.
Your business likely requires different sets of KYC information depending on the type of customer. You can define the labels for each of these customer types in your
dev.assets.yaml file, and your sending organizations will need to understand which label to use when registering or querying the status of customers.
PUT /customer requests, you should use the type passed to evaluate whether the sender has provided all of the required fields. In
GET /customer requests, you should use the type to determine the customer's status.
Test with the Demo Wallet
You can test your implementation with the Stellar Demo Wallet following the steps below.
- Select "Generate keypair for new account"
- Select "Create account"
- Select "Add Asset" and enter the asset code and the Anchor Platform's home domain,
- Select "Add trustline"
- Fund your account with a balance of the asset
- Select "SEP-31 Send" in the dropdown menu
You should see the demo wallet find your service URLs, authenticate, and check which KYC fields it needs to collect. It should then present a form for you to enter the KYC details for the sender and reciever.
Once you've entered in the information requested, it will send that information to the Anchor Platform, which will send it to your business server. Once the demo wallet has the customers' IDs you generated, it will initiate a transaction which should fail.
Rate Callback Endpoint
Once the sending organization has registered the customers involved in the transaction, it will need to request a quote, or FX rate, from your business. The Anchor Platform requests this information from your business server using the
GET /rate endpoint.
Firm vs. Indicative Quotes
Requests for quotes will have a
type parameter that is either
type=firm, your response must include the
expires_at date-time field and reserve the liquidity needed to fulfil this quote until the quote expires. If
type=indicative, do not return
expires_at fields because the rate provided will not be used in a transaction.
Note that the client may request that the quote expires after a specific date-time using the
expires_after parameter. Your business must honor this request by returning an
expires_at value that is at or after the requested date-time or reject the request with a 400 Bad Request response, which will be forwarded to the client.
Using the Client ID
Requests may include a
client_id parameter that identifies the sending organization requesting the rate. You can use this parameter to adhere to the commercial terms agreed upon with that sending organization, such as offering discounted rates.
client_id may not be present for indicative requests, in which case your market price should be returned. Currently
client_id will always be the Stellar public key the sending organization used to authenticate with the Anchor Platform.
It is common for businesses' rates and fees to differ depending on the payment rails used to send funds to the recipient. If your delivery methods are configured in your
asset.yaml file, clients will always provide the payment rail they want your business to use for firm quote requests.
Because this endpoint is currently only used paying out remittances in off-chain assets, the
buy_delivery_method will be used. If this endpoint is ever used in other transaction flows such as SEP-24 deposits, then
sell_delivery_method may also be passed for business that support these types of transactions.
Fetching Transaction Status Updates
To facilitate cross-border payments, you'll need to be able to detect when a sending organization has sent your business an on-chain payment and determine which transaction that payment was meant to fulfil.
The easiest way to do that is to run the Stellar Observer, which will detect these payments and update the corresponding transaction record with information about the payment. Your business can then detect these updates by polling the
GET /transactions Platform API endpoint.
Running the Stellar Observer
The Stellar Observer monitors the Stellar ledger for payments made to your account(s) and updates the corresponding transaction records with on-chain payment information. To run the observer, add the following to your docker compose file.
Polling for Received Payments
The Stellar Observer makes
PATCH /transactions requests to the Platform API whenever it detects payments received for transactions initiated by sending organizations, updating the transaction's
transfer_received_at date-time. Your business should periodically poll the
GET /transactions Platform API endpoint to detect these updates like so.
The response will include a list of cross-border payment transactions initiated by sending organizations ordered by when a payment was received for that transaction. For each transaction returned, your business should check whether or not it has already detected the payment for that transaction. If it has, you have detected all payments made to your account(s).
Providing Transaction Status Updates
Once your business detects that it has received an on-chain payment for a specific transaction, it must make the off-chain payment to the recipient and update the transaction's status to
completed via a
PATCH /transactions request.
"message": "a deposit to the recipient's bank has been initiated"
Fee Callback Endpoint
Your business may want to offer sending organizations the option to skip the quote creation process, allowing your business to use a rate determined at the time funds are paid out to the recipient. In this case, the Anchor Platform will not make a
GET /rate request, but you will still need to provide the fee your business will charge for these types of transactions using the
GET /fee endpoint.
You can enable these types of transactions by updating your
assets.yaml file configuration:
Unique Address Callback Endpoint
Businesses must provide a unique Stellar account and memo pair for each transaction requested by sending organizations so the Anchor Platform can identify and map the on-chain payment sent for the specific transaction. The Anchor Platform can generate these account & memo pairs itself, but most businesses use a custodial service to receive on-chain payments, in which case the business must request the custodian to generate the Stellar account & memo. This is done using the
GET /unique_address endpoint.
To configure the Anchor Platform to make these requests, add the following to your configuration:
This endpoint may be removed in future major version updates of the Anchor Platform when it adds support for connecting to custodial services and generating these addresses automatically.