Integration
Integrating with the Anchor Platform for facilitating cross-border payments involves implementing the following, at a mimimum:
GET /customer
&PUT /customer
KYC API endpoints to request & collect customers' KYC dataGET /rate
RFQ API endpoint to provide FX rates between the on & off-chain assets supportedGET /transactions
requests to fetch updates on the Anchor Platform's transactions' statuses (documentation coming soon)PATCH /transactions
requests to update the Anchor Platform's transactions' statuses
The following may also be required depending on your use case:
GET /fee
if your business wants to provide senders the option to skip the quote creation stepGET /unique_address
if your business uses a custody service for on-chain assetsDELETE /customer
if 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.
- YAML
version: "3.8"
services:
sep-server:
image: stellar/anchor-platform:2.0.1
command: --sep-server
env_file:
- ./dev.env
volumes:
- ./config:/home
ports:
- "8080:8080"
depends_on:
- db
platform-server:
image: stellar/anchor-platform:2.0.1
command: --platform-server
env_file:
- ./dev.env
volumes:
- ./config:/home
ports:
- "8085:8085"
depends_on:
- db
server:
build: .
ports:
- "8081:8081"
env_file:
- ./dev.env
db:
image: postgres:14
ports:
- "5432:5432"
env_file:
- ./dev.env
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.
Identifying Customers
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:
- JSON
{
"account": "GDJUOFZGW5WYBK4GIETCSSM6MTTIJ4SUMCQITPTLUWMQ6B4UIX2IEX47",
"memo": "780284017",
"type": "sep31-sender",
"first_name": "John",
"last_name": "Doe",
"email": "[email protected]"
}
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.
- JSON
{
"id": "fb5ddc93-1d5d-490d-ba5f-2c361cea41f7"
}
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:
- Example
/customer?account=GDJUOFZGW5WYBK4GIETCSSM6MTTIJ4SUMCQITPTLUWMQ6B4UIX2IEX47&memo=780284017&type=sep31-sender
Or, the sending organziation could use the identifier you returned when they originally registered the customer.
- Example
/customer?id=fb5ddc93-1d5d-490d-ba5f-2c361cea41f7&type=sep31-sender
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.
Customer Types
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.
In 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,
localhost:8080
- 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 indicative
or firm
. If type=firm
, your response must include the id
& expires_at
date-time field and reserve the liquidity needed to fulfil this quote until the quote expires. If type=indicative
, do not return id
or 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.
Delivery Methods
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.
- YAML
services:
...
observer:
image: stellar/anchor-platform:2.0.1
command: --stellar-observer
env_file:
- ./dev.env
volumes:
- ./config:/home
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.
- bash
curl http://localhost:8080/transactions?sep=31&order_by=transfer_received_at&order=desc
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.
- JSON
{
"transaction": {
"id": "<id>",
"status": "completed",
"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.
Configuration
You can enable these types of transactions by updating your assets.yaml
file configuration:
- YAML
assets:
- ...
sep31:
quotes_required: false
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.
Configuration
To configure the Anchor Platform to make these requests, add the following to your configuration:
- bash
# dev.env
SEP31_DEPOSIT_INFO_GENERATOR_TYPE=api
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.