Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SEP31: Added SEP-12 logic #660

Merged
merged 10 commits into from
Jul 6, 2020
116 changes: 54 additions & 62 deletions ecosystem/sep-0031.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,25 +65,25 @@ This protocol involves the transfer of value, and so HTTPS is required for all e
### User Onboarding

1. User onboarding happens with the sending anchor, and is out of the scope of this spec.
1. Sending anchor should use this to collect any KYC about the receiver it will need so it doesn't have to do it at every transaction.
2. The sending anchor should, at minimum, collect the KYC information of the sending and receiving users specified by the receiving anchor's [SEP-12](sep-0012.md) implementation.

### Payment Flow

1. Payment initiation happens in the sending anchors interface, and is also out of the scope of this spec.
1. The sending client chooses a destination region.
1. The sending anchor fetches the TOML file to find the DIRECT_PAYMENT_SERVER API root and [`/info`](#info) endpoint fields for the receiving anchor for this region.
1. Using the fields fetched from /info, the sending anchor collects all needed information from the sending client.
1. The sending anchor POSTs all that information to the [/send](#send) endpoint of the receiving anchor.
1. If information is missing, or the receiving anchor needs extra information to complete this transaction, `POST /send` will return `400 Customer Information Needed` along with the missing fields. The sending anchor should collect these and retry the entire `POST /send` call, until it succeeds.
1. Once all needed information is provided and the receiving anchor is ready to complete this transaction, the `POST /send` call will return a `200` status along with information needed to complete the transaction over the stellar network.
1. For each `_sep12_type` value specified in the relevant asset's [`/info`](#info) object, the sending anchor makes a [`SEP-12 GET /customer`](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0012.md#customer-get) request.
1. The sending anchor collects all information specified in the `GET /customer` response(s).
1. The sending anchor PUTs all that information to the [`/customer`](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0012.md#customer-put) endpoint of the receiving anchor.
1. The sending anchor POSTs the transaction information to the [/send](#send) endpoint of the receiving anchor.
1. If some of the information POSTed was missing or incorrect, or the `amount` is value is large enough to require additional information, the receiving anchor returns a `400` error response using either the `transaction_info_needed` or `customer_info_needed` status strings. More information about these responses can be found in the [/send](#send) section.
1. Once the sending anchor has provided all the required information and the receiving anchor is ready to complete this transaction, the `POST /send` call will return a `200` status along with information needed to complete the transaction over the stellar network.
1. The sending anchor should collect the fiat from the sending client, and perform the specified stellar transaction to send the money to the receiving anchor. This is usually a path payment, but can be done with a regular payment as well, so long as the receiving anchor gets the token they expect.
1. Once the stellar transaction is completed, the receiving anchor should deposit the money in the receivers bank account.
1. If the receiver finds out during a bank deposit that some of the receivers information is incorrect, the transaction should be placed in the `pending_info_update` status so the sender can correct it.
1. The sending anchor can query the status of this transaction via the [`/transaction`](#transaction) endpoint, and should communicate updates to the sending client as that progresses. If the status is `pending_info_update` it should request that info from the sending client and provide it to the receiving anchor via the [`/update`](#update) endpoint.
1. If the sender finds out during a bank deposit that some of the receivers information is incorrect, the transaction should be placed in either the `pending_customer_info_update` or `pending_transaction_info_update` status so the sender can correct it. More information on these status values can be found in the [/transaction](#transaction) section.
1. The sending anchor can query the status of this transaction via the [`/transaction`](#transaction) endpoint, and should communicate updates to the sending client as it changes.
1. Once the [`/transaction`](#transaction) endpoint returns a `completed` status the transaction has been completed.



## API Endpoints

* [`GET /info`](#info)
Expand Down Expand Up @@ -119,31 +119,14 @@ The response should be a JSON object like:
"fee_percent":1,
"min_amount":0.1,
"max_amount":1000,
"sender_sep12_type": "sep31-sender",
"receiver_sep12_type": "sep31-receiver",
"fields":{
"sender":{
"first_name": {
"description": "The sender's first name"
},
"last_name": {
"description": "The sender's last name"
}
},
"receiver":{
"first_name": {
"description": "The receiver's first name"
},
"last_name":{
"description": "The receiver's last name"
},
"email_address": {
"description": "The receiver's email address"
}
},
"transaction":{
"routing_number":{
"receiver_routing_number":{
"description": "routing number of the destination bank account"
},
"account_number":{
"receiver_account_number":{
"description": "bank account number of the destination"
},
"type":{
Expand All @@ -168,15 +151,19 @@ The JSON object contains an entry for each asset that the anchor supports for re
* `max_amount`: Optional maximum amount. No limit if not specified.
* `fee_fixed`: Optional fixed (flat) fee for deposit. In units of the received asset. Leave blank if there is no fee or the fee schedule is complex.
* `fee_percent`: Optional percentage fee for deposit. In percentage points. Leave blank if there is no fee or the fee schedule is complex.
* `fields` object as explained below.
* `sender_sep12_type`: The value of the `type` parameter the sending anchor should use for a `SEP-12 GET /customer` request.
* `receiver_sep12_type`: The value of the `type` parameter the sending anchor should use for a `SEP-12 GET /customer` request.
* `fields`: as explained below.

The `fields` object allows an anchor to describe fields that must be passed into `POST /send`. It should include any KYC fields required for the sender or receiver, account information, and anything else required by the receiving anchor in order to complete a transaction. Fields are broken out by `sender`, `receiver`, and `transaction`. `sender` and `receiver` contain KYC requests of values from SEP-9 while `transacton` contains transaction specific information requested.
The `fields` object allows an anchor to describe fields that must be passed into `POST /send`. Only fields related to the transaction should be described in the `fields` object. In the example above, the receiving anchor requires the account and routing number of the receiving client's bank account.

Each `fields` sub-object contains a key for each field name and an object with the following fields as the value:

* `description`: (required) description of field to show to user.
* `choices`: (optional) list of possible values for the field.
* `optional`: (optional) field true if this field is not required to be provided
* `optional`: (optional) false if not specified.

Information on the sending and receiving clients should be described by the receiving anchor and sent by the sending anchor via [SEP-12](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0012.md#customer-get). `sender_sep12_type` and `receiver_sep12_type` specify the values the sending anchor should use for the [type](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0012.md#type-specification) parameter to `GET /customer`, which the receiving anchor will use to respond with the fields needed for each type.

### Send

Expand All @@ -191,25 +178,18 @@ Content-Type: application/json
"asset_code": "USD",
"asset_issuer": "GDRHDSTZ4PK6VI3WL224XBJFEB6CUXQESTQPXYIB3KGITRLL7XVE4NWV",
"fields": {
"sender": {
"first_name": "Alice",
"last_name": "Jones"
},
"receiver": {
"first_name": "Bob",
"last_name": "Dillon",
"email_address": "bdillon@something.com"
},
"sender_id": 123,
"receiver_id": 456,
"transaction": {
"routing_number": "442928834",
"account_number": "0029483242",
"receiver_routing_number": "442928834",
"receiver_account_number": "0029483242",
"type": "SEPA"
}
}
}
```

This post requests attempts to initiate a payment through this anchor. It should provide the amount and all the required fields (specified in the [`/info`](#info) endpoint).
This post requests attempts to initiate a payment through this anchor. It should provide the amount and all the required fields (specified in the [`/info`](#info) endpoint). The values for `sender_id` and `receiver_id` are from the receiving anchor's [SEP-12](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0012.md#customer-put) `PUT /customer` responses.

If the request describes a valid transaction that this anchor can fulfill, we return a success response with details on what to send. If the request is not valid, or we need more info, we can return with an error response and expect the sending anchor to try again with updated values.

Expand Down Expand Up @@ -237,12 +217,20 @@ Name | Type | Description

##### Customer Info Needed (400 Bad Request)

In the case where the sending anchor didn't provide all the information requested in `/info`, or if the transacton requires extra information, the request should fail with a 400 status code and the following body in JSON format. The sender should then retry the entire request including all the previously sent fields plus the fields described in the response.
In the case where the sending anchor didn't provide all the KYC information requested in `GET /customer`, or where the receiver requires additional KYC information after learning of the transaction `amount`, the request should fail with a 400 status code and the following body in JSON format. The sender should then retry both the `GET /customer` request to collect the additional fields and the `PUT /customer` request including all fields described in the `GET /customer` response.
JakeUrban marked this conversation as resolved.
Show resolved Hide resolved

Name | Type | Description
-----|------|------------
`error`| string | `customer_info_needed`
`fields` | object | A key-value pair of missing fields in the same format as fields described in [`/info`](#info), broken out by sender, receiver, and transacton.

##### Transaction Info Needed (400 Bad Request)

In the case where the sending anchor didn't provide all the information requested in `/info`, or if the transacton requires extra information, the request should fail with a 400 status code and the following body in JSON format. The sender should then retry the entire request including all the previously sent fields plus the fields described in the response.

Name | Type | Description
-----|------|------------
`error`| string | `transaction_info_needed`
`fields` | object | A key-value pair of missing fields in the same format as fields described in [`/info`](#info).

##### Error (400 Bad Request)

Expand Down Expand Up @@ -297,13 +285,14 @@ Name | Type | Description
`external_transaction_id` | string | (optional) ID of transaction on external network that either completes the payment into the receivers account.
`refunded` | boolean | (optional) Should be true if the transaction was refunded. Not including this field means the transaction was not refunded.
`required_info_message` | string | (optional) A human readable message indicating any errors that require updated information from the sender
`required_info_updates` | object | (optional) A set of fields that require upate from the sender, in the same format as described in [/info](#info). Fields should be broken out by sender, receiver, and transacton as in /info.
`required_info_updates` | object | (optional) A set of fields that require update from the sender, in the same format as described in [/info](#info). This field is only relevant when `status` is `pending_transaction_info_update`.

`status` should be one of:

* `pending_sender` -- awaiting payment to be initiated by sending anchor
* `pending_stellar` -- transaction has been submitted to Stellar network, but is not yet confirmed.
* `pending_info_update` -- certain pieces of information need to be updated by the sending anchor. See [pending info update](#pending-info-update) section
* `pending_customer_info_update` -- certain pieces of information need to be updated by the sending anchor. See [pending customer info update](#pending-customer-info-update) section
* `pending_transaction_info_update` -- certain pieces of information need to be updated by the sending anchor. See [pending transaction info update](#pending-transaction-info-update) section
* `pending_receiver` -- payment is being processed by the receiving anchor
* `pending_external` -- payment has been submitted to external network, but is not yet confirmed.
* `completed` -- deposit/withdrawal fully completed.
Expand Down Expand Up @@ -338,11 +327,12 @@ Example response:
"amount_out": "18.24",
"amount_fee": "0.1",
"started_at": "2017-03-20T17:05:32Z",
"required_info_message": "The bank reported an incorrect name for the receiver, please ensure the name matches legal documents",
"required_info_message": "The bank reported an incorrect account number for the receiver, please ensure the account matches legal documents",
"required_info_updates": {
"receiver": {
"first_name":"The receiver's first name",
"last_name":"The receiver's last name"
"transaction": {
"receiver_account_number": {
"description": "The receiver's bank account number"
}
}
}
}
Expand All @@ -351,15 +341,17 @@ Example response:

If the transaction cannot be found, the endpoint should return a `404 NOT FOUND` result.

#### Pending info update
#### Pending customer info update

In certain cases the receiver might need to request updated information, for example if the bank tells them that the provided receiver name is incorrect, or missing a middle initial. In this case, the transaction should go into the `pending_info_update` state until the sender provides updates.
In certain cases the receiver might need to request updated information. For example, if the bank tells the anchor that the provided receiver last name is incorrect, or missing a middle initial. Since this information was sent via SEP-12, the transaction should go into the `pending_customer_info_update` state until the sender makes another `PUT /customer` request to update. The sending anchor can check which fields need to be updated by making a `GET /customer` request including the `id` or `account` & `memo` parameters. The receiving anchor should respond with a `NEEDS_INFO` status and `last_name` included in the fields described.

### Update
#### Pending transaction info update

The `/update` endpoint allows for updating certain pieces of information that need to be corrected. For example a bank may reject a deposit because a name is mis-spelled, or a middle initial is missing. This allows transactions to be updated instead of errored and refunded.
Another possibility is that the bank tells the receiving anchor that the provided account or routing number is incorrect. Since this information was sent via a `POST /send` request, the transaction should go into the `pending_transaction_info_update` state until the sender makes a request to the endpoint outlined below.

### Update

This endpoint should only be used when the receiver requests more info via the `pending_info_update` status. If the sender tries to update at a time when no info is requested the receiver should fail with an error response.
This endpoint should only be used when the receiver requests more info via the `pending_transaction_info_update` status. The `required_info_updates` transaction field should contain the fields required for the update. If the sender tries to update at a time when no info is requested the receiver should fail with an error response.

```
PUT DIRECT_PAYMENT_SERVER/update
Expand All @@ -370,7 +362,7 @@ Request parameters:
Name | Type | Description
-----|------|------------
`id` | string | The id of the transaction.
`fields` | object | A key-pair object containing the values requested to be updated by the receiving anchor.
`fields` | object | A key-pair object containing the values requested to be updated by the receiving anchor in the same format as [`/send`](#send).

#### Example

Expand All @@ -380,9 +372,9 @@ PUT DIRECT_PAYMENT_SERVER/update
{
id: "82fhs729f63dh0v4",
fields: {
receiver: {
first_name: "Bob",
last_name: "Jones"
transaction: {
receiver_bank_account: 12345678901234,
receiver_routing_number: 021000021
}
}
}
Expand Down