Skip to content

Latest commit

 

History

History
797 lines (691 loc) · 38.5 KB

dip-158.md

File metadata and controls

797 lines (691 loc) · 38.5 KB
dip title authors co-authors status type created
158
P2M (eCommerce) Payments Off-Chain Protocol
Yinon Zohar, Daniel Prinz
David Wolinsky, Dimitri Roche
Draft
Standard
03/15/2021

Summary

This DIP leverages the off-chain protocol defined in DIP-1 and extends it to enable eCommerce P2M payments (Peer To Merchant) of the following types:

  • Charge
  • Auth / Capture

This DIP defines the type of eCommerce P2M payments, corresponding requests and the payment structures.

This DIP makes the Auth/Capture section in DIP-8 redundant. The auth/capture section in DIP-8 is to be disregarded and will be removed in a future version of DIP-8.

This DIP does NOT include payment flows which require funds pull pre-approval such as subscription and recurring payments.

This DIP makes use of the result field added to the CommandResponseObject as described in DIP-161


Abstract / Motivation

This DIP is an extension of the Off-Chain Protocol to support more advanced payment functionality - particularly eCommerce P2M payments.

How P2M Payments Differ from P2P Transfers

There are several key differences between the process of paying a merchant (P2M) and a simple P2P transfer:

P2M P2P
Payer Data Customer details are required for every payment / purchase in order to perform risk checks and apply AML policies Required only for transfers for which Travel Rule applies. i.e., over 1000 USD
Payment Owner The merchant, i.e. the receiver of funds, "drives" the process and controls the type of payment and its timing. For example, the merchant will decide when to capture the previously authorized funds and whether to capture the entire payment amount or only partial amount The payer, i.e. the sender of funds, determines the nature of the transfer
Reconciliation The merchant requires a way to correlate the transfer of funds to a payment or payment request for reconciliation purposes No reconciliation

P2M Payment Types

There are two types of P2M payments described in this document:

  1. Charge. Charge payment stipulates an immediate capture of funds. This means that a successful off-chain negotiation for such payment will result in funds being captured
  2. Auth / Capture. Auth / Capture payment, as the name suggests, means that the payment is divided to two steps: Authorization and Capture. Successful Authorization implies that the funds are locked so they can later be captured

Glossary

For the sake of simplicity, we use the following terms:

  • "Sender", "Payer", "Wallet" or "customer VASP" - The customer's wallet. It is the VASP representing the customer. This is the VASP that will send the funds and eventually will submit the on-chain transaction to the blockchain
  • "Receiver", "Receiving VASP" or "Merchant VASP" - The VASP representing the merchant which receives the funds (transaction)
  • "Customer" - The person who wishes to pay the merchant for goods or services
  • "Reference ID", "Common Payment Identifier", "Payment Identifier" - A unique identifier of the payment. It must be a UUID according to RFC4122 with "-"'s included. See also Reference ID in DIP-1

Prerequisite: Sharing Payment Identifier and Receiver Address

A prerequisite for the off-chain negotiations is that both parties (sending and receiving VASPs) have shared a common payment identifier and the receiver address. This common payment identifier is required to support a successive off-chain protocol between the VASPs. This DIP specifies a couple of examples for exchanging identifiers between VASPs, however, there could be others. The protocol is agnostic to the method of exchanging the common payment identifier.

See Appendix A


P2M Off-Chain Protocol Specification

This section specifies P2M payment types, required structures, payloads and expected sequence of calls based on this protocol.

Content:


High-Level Flow and Payment Types


The high-level flow of an eCommerce P2M payment (regardless of the type) is:

  1. On the merchant's checkout page the customer chooses to pay with Diem
  2. The merchant transmits the payment details to its VASP (receiver VASP) so the latter can generate a payment request with Diem
  3. The the receiver VASP generates a payment request with all details needed to identify this payment later in the process, provides it to the merchant and makes it available to the customer's Diem wallet (the customer's VASP or sender)
  4. The sender VASP parses the payment request (e.g. by scanning the payment request QR) and uses the provided payment identifier to get the payment details. This is the first step of the off-chain protocol
  5. The wallet then presents the requested payment details to the customer so the customer can review the payment
  6. The customer approves the payment request in the wallet
  7. The wallet initializes the payment protocol (off-chain) which will end (if successful) with the funds being authorized or charged (depending on the payment type). Successful completion implies that the receiving VASP was satisfied with the payer information provided and the sender VASP was satisfied with the merchant information provided. Note that if the payment amount exceeds the amount that requires a dual attestation signature to be submitted to the blockchain, it must be part of the on-chain transaction submitted

Charge Payment Type

Charge payment stipulates an immediate capture of funds. This means that a successful off-chain negotiation for such payment will result in funds being captured.

As soon as the funds are captured, i.e. the sender agreed to the payment terms, the sender VASP is expected to submit a corresponding transaction on-chain and actually transfer the funds.

Auth / Capture Payment Type

Auth / Capture payment, as the name suggests, means that the payment is divided into two steps:

  • Authorization
  • Capture

The Authorization step ends when the funds are locked by the sender VASP so they can later be captured by the receiver VASP. Note that the capture may occur several days after a successful authorization. It is up to the receiver VASP to decide on the timing. In addition, the receiver may choose to capture only a partial amount rather than the full amount which was authorized.

This payment type is useful for delayed fulfillment or pre-authorizing an expected amount to ensure that an amount can be captured after services are rendered.

Off-chain negotiations for Auth / Capture payment are divided into two steps accordingly. First, off-chain negotiations will result in funds being authorized, i.e. locked by the wallet. Later, a separate off-chain negotiation triggered by the receiving VASP will capture the funds. Note that for the time being, multi-capture is not supported and there can be only a single capture request.

Successful authorization will not necessarily be followed by a successful capture. It is possible that the receiver will choose to cancel the authorization and essentially void the payment before it was captured. One possible reason to void a payment is that the products for which an amount was locked are out of stock and cannot be fulfilled.


Sender / Receiver Interface


This section describes a set of functionalities / activities that should be made available by a Sender and Receiver VASPs in order to support P2M flows based on this DIP. Each functionality can be conceptually compared to an API endpoint. Similar to API documentation, it includes the expected input and output for each functionality.

New Command Types

The following is a list of new values for the command_type field of the CommandRequestObject. Each command type denotes a step in the off-chain negotiations and specifies the data of the requests and the response

  • GetInfoCommand - Allows obtaining payment information based on reference id
  • InitChargeCommand - Initializes a payment process of type charge
  • InitAuthorizeCommand - Initializes a payment process of type auth
  • ReadyForSettlementNotification - Notifies the payment is ready for settlement on-chain
  • AuthorizedNotification - Notifies that payment funds are authorized (locked) for future capture
  • CaptureCommand - Request to capture authorized (locked) funds
  • VoidCommand - Voids a payment
  • AbortCommand - Aborts a payment
Command Type Direction Description Request Data Response Data
GetInfoCommand Sender > Receiver By providing the object reference id the wallet can retrieve the object information from the receiving VASP. In most cases, this would be the first command sent by the wallet. The wallet is not expected to provide any payer data at this stage Reference ID Payment Details ; Business Data
InitChargeCommand Sender > Receiver This functionality allows the wallet to init the payment process based on the payment details. For example, this may occur after the customer approved the payment request Reference ID ; Payer Data (optional) Recipient Signature
InitAuthorizeCommand Sender > Receiver This functionality allows the wallet to init the payment process based on the payment details. For example, this may occur after the customer approved the payment request Reference ID ; Payer Data
ReadyForSettlementNotification Sender > Receiver This functionality allows the wallet to indicate the payment is ready for settlement. The wallet is expected to submit a transaction on-chain immediately before or after declaring it is ready Reference ID
AuthorizedNotification Sender > Receiver This functionality allows the wallet to indicate funds are locked for future capture. Relevant only for Auth / Capture payments Reference ID
CaptureCommand Receiver > Sender This functionality allows the receiver to capture the locked (authorized) funds or part of it. Relevant only for Auth / Capture payments. This optionally includes the recipient signature for dual attestation scenario if needed Reference ID ; (optional) Amount ; (optional) Recipient Signature
VoidCommand Receiver > Sender This functionality allows the receiver to void the payment. For example, the merchant voided the payment because the purchased products are out of stock. Relevant only for Auth / Capture payments Reference ID
AbortCommand Sender > Receiver / Receiver > Sender This functionality allows both parties to abort the payment. For example, the receiver may want to abort the payment following failed risk checks Reference ID

Request / Response Payload


The following section describes the request/response payloads of the different functionalities.

GetInfoCommand

Command Type Direction Description Request Data Response Data
GetInfoCommand Sender > Receiver By providing the object reference id the wallet can retrieve the object information from the receiving VASP. In most cases, this would be the first command sent by the wallet. The wallet is not expected to provide any payer data at this stage Reference ID Payment Details ; Business Data

GetInfoCommand Request

Field Type Required? Description
reference_id str Y Unique reference ID of this payment. This value should be globally unique
{
  "_ObjectType": "CommandRequestObject",
  "command_type": "GetInfoCommand",
  "cid": "3185027f-0574-6f55-2668-3a38fdb5de98",
  "command": {
    "_ObjectType": "GetInfoCommand",      
    "reference_id": "4185027f-0574-6f55-2668-3a38fdb5de98"   
  }
}

GetInfoCommand Response

Field Type Required? Description
payment_info PaymentInfoObject Y The minimal payment details required in order for the payer to decide whether to accept the payment or reject it.
{
  "_ObjectType": "CommandResponseObject",
  "status": "success",
  "cid": "12ce83f6-6d18-0d6e-08b6-c00fdbbf085a",
  "result": {
    "_ObjectType": "GetInfoCommandResponse",
    "payment_info": {      
      "receiver": {
        "account_address": "dm1pllhdmn9m42vcsamx24zrxgs3qqqpzg3ng32kvacapx5fl",         
        "business_data": {
          "name": "Acme",
          "legal_name": "Acme Technologies Inc.",
          "address": {
            "city": "San Francisco",
            "country": "US",
            "line1": "1260 Market Street",
            "line2": "Suite 450",
            "postal_code": "94103",
            "state": "CA"
          }
        }        
      },
      "action": {
        "amount": "100000000",
        "currency": "XUS",
        "action": "charge",
        "timestamp": "72322"
      },
      "reference_id": "4185027f-0574-6f55-2668-3a38fdb5de98",
      "description": "payment request description"     
    }
  }
}

InitChargeCommand

Command Type Direction Description Request Data Response Data
InitChargeCommand Sender > Receiver This functionality allows the wallet to init the payment process for payments of type charge based on the payment details. For example, this may occur after the customer approved the payment request Reference ID ; Payer Data

InitChargeCommand Request

Field Type Required? Description
sender PaymentSenderObject Y Minimal payer information required for the receiving VASP to enforce AML and perform risk checks
reference_id str Y Unique reference ID of this payment. This value should be globally unique
{
  "_ObjectType": "CommandRequestObject",
  "command_type": "InitChargeCommand",
  "cid": "3185027f-0574-6f55-2668-3a38fdb5de98",
  "command": {
    "_ObjectType": "InitChargeCommand",
    "sender": {
      "account_address": "dm1pg9q5zs2pg9q5zs2pg9q5zs2pg9skzctpv9skzcg9kmwta",
      "payer_data": {
        "given_name": "Alice",
        "surname": "Cooper",
        "address": {
          "city": "Sunnyvale",
          "country": "US",
          "line1": "1234 Maple Street",
          "line2": "Apartment 123",
          "postal_code": "12345",
          "state": "California"
        },
        "national_id_data": {
          "id_value": "123456789",
          "country": "US",
          "type": "SSN"
        } 
      }          
    },
    "reference_id": "4185027f-0574-6f55-2668-3a38fdb5de98"			    
  }                      
}

InitChargeCommand Response

Field Type Required? Description
recipient_signature str N Signature of the recipient of this transaction encoded in hex. A metadata payload is signed with the compliance key of the recipient VASP and is used for on-chain attestation from the recipient party. This may be omitted on Blockchains which do not require on-chain attestation. Generated via Recipient Signature.
{
  "_ObjectType": "CommandResponseObject",
  "status": "success",
  "cid": "12ce83f6-6d18-0d6e-08b6-c00fdbbf085a",
  "result": {
    "_ObjectType": "InitChargeCommandResponse",
    "recipient_signature": "..."
  }
}

InitAuthorizeCommand

Command Type Direction Description Request Data Response Data
InitChargeCommand Sender > Receiver This functionality allows the wallet to init the payment process for payments of type auth based on the payment details. For example, this may occur after the customer approved the payment request Reference ID ; Payer Data

InitAuthorizeCommand Request

Field Type Required? Description
sender PaymentSenderObject Y Minimal payer information required for the receiving VASP to enforce AML and perform risk checks
reference_id str Y Unique reference ID of this payment. This value should be globally unique
{
  "_ObjectType": "CommandRequestObject",
  "command_type": "InitAuthorizeCommand",
  "cid": "3185027f-0574-6f55-2668-3a38fdb5de98",
  "command": {
    "_ObjectType": "InitAuthorizeCommand",
    "sender": {
      "account_address": "dm1pg9q5zs2pg9q5zs2pg9q5zs2pg9skzctpv9skzcg9kmwta",
      "payer_data": {
        "given_name": "Alice",
        "surname": "Cooper",
        "address": {
          "city": "Sunnyvale",
          "country": "US",
          "line1": "1234 Maple Street",
          "line2": "Apartment 123",
          "postal_code": "12345",
          "state": "California"
        },
        "national_id_data": {
          "id_value": "123456789",
          "country": "US",
          "type": "SSN"
        } 
      }          
    },
    "reference_id": "4185027f-0574-6f55-2668-3a38fdb5de98"			    
  }                      
}

InitAuthorizeCommand Response

{
  "_ObjectType": "CommandResponseObject",
  "status": "success",
  "cid": "12ce83f6-6d18-0d6e-08b6-c00fdbbf085a"
}

ReadyForSettlementNotification

Command Type Direction Description Request Data Response Data
ReadyForSettlementNotification Sender > Receiver This functionality allows the wallet to indicate the payment is ready for settlement. The wallet is expected to submit a transaction on-chain immediately before or after declaring it is ready Reference ID

ReadyForSettlementNotification Request

Field Type Required? Description
reference_id str Y Unique reference ID of this payment. This value should be globally unique
{
  "_ObjectType": "CommandRequestObject",
  "command_type": "ReadyForSettlementNotification",
  "cid": "3185027f-0574-6f55-2668-3a38fdb5de98",
  "command": {
    "_ObjectType": "ReadyForSettlementNotification",      
    "reference_id": "4185027f-0574-6f55-2668-3a38fdb5de98"
  }
}

ReadyForSettlementNotification Response

{
  "_ObjectType": "CommandResponseObject",
  "status": "success",
  "cid": "12ce83f6-6d18-0d6e-08b6-c00fdbbf085a"    
}

AuthorizedNotification

Command Type Direction Description Request Data Response Data
AuthorizedNotification Sender > Receiver This functionality allows the wallet to indicate funds are locked for future capture. Relevant only for Auth / Capture payments Reference ID

AuthorizedNotification Request

Field Type Required? Description
reference_id str Y Unique reference ID of this payment. This value should be globally unique
{
  "_ObjectType": "CommandRequestObject",
  "command_type": "AuthorizedNotification",
  "cid": "3185027f-0574-6f55-2668-3a38fdb5de98",
  "command": {
    "_ObjectType": "AuthorizedNotification",
    "reference_id": "4185027f-0574-6f55-2668-3a38fdb5de98"
  }  
}

AuthorizedNotification Response

{
  "_ObjectType": "CommandResponseObject",
  "status": "success",
  "cid": "12ce83f6-6d18-0d6e-08b6-c00fdbbf085a"    
}

CaptureCommand

Command Type Direction Description Request Data Response Data
CaptureCommand Receiver > Sender This functionality allows the receiver to capture the locked (authorized) funds or part of it. Relevant only for Auth / Capture payments Reference ID ; (optional) Amount ; (optional) Recipient Signature

CaptureCommand Request

Field Type Required? Description
reference_id str Y Unique reference ID of this payment. This value should be globally unique
amount uint N Amount to capture. Base units are the same as for on-chain transactions for this currency. Amount can equal or lower than the authorized amount
currency enum N One of the supported on-chain currency types, e.g. XUS. Must be the same as the authorized currency
recipient_signature str N Signature of the recipient of this transaction encoded in hex. A metadata payload is signed with the compliance key of the recipient VASP and is used for on-chain attestation from the recipient party. This may be omitted on Blockchains which do not require on-chain attestation. Generated via Recipient Signature
{
  "_ObjectType": "CommandRequestObject",
  "command_type": "CaptureCommand",
  "cid": "3185027f-0574-6f55-2668-3a38fdb5de98",
  "command": {
    "_ObjectType": "CaptureCommand",      
    "reference_id": "4185027f-0574-6f55-2668-3a38fdb5de98", 
    "recipient_signature": "..."
  }
}

CaptureCommand Response

{
  "_ObjectType": "CommandResponseObject",
  "status": "success",
  "cid": "12ce83f6-6d18-0d6e-08b6-c00fdbbf085a"    
}

VoidCommand

Command Type Direction Description Request Data Response Data
VoidCommand Receiver > Sender This functionality allows the receiver to void the payment. For example, the merchant voided the payment because the purchased products are out of stock. Relevant only for Auth / Capture payments Reference ID

VoidCommand Request

Field Type Required? Description
reference_id str Y Unique reference ID of this payment. This value should be globally unique
void_message str N Additional information about the reason for voiding this payment
{
  "_ObjectType": "CommandRequestObject",
  "command_type": "VoidCommand",
  "cid": "3185027f-0574-6f55-2668-3a38fdb5de98",
  "command": {
    "_ObjectType": "VoidCommand",
    "reference_id": "4185027f-0574-6f55-2668-3a38fdb5de98",
    "void_message": "void message"
  }
}

VoidCommand Response

{
  "_ObjectType": "CommandResponseObject",
  "status": "success",
  "cid": "12ce83f6-6d18-0d6e-08b6-c00fdbbf085a"
}

AbortCommand

Command Type Direction Description Request Data Response Data
AbortCommand Sender > Receiver / Receiver > Sender This functionality allows both parties to abort the payment. For example, the receiver may want to abort the payment following failed risk checks Reference ID

AbortCommand Request

Field Type Required? Description
reference_id str Y Unique reference ID of this payment. This value should be globally unique
abort_message str N Additional information about the reason for aborting this payment
{
  "_ObjectType": "CommandRequestObject",
  "command_type": "AbortCommand",
  "cid": "3185027f-0574-6f55-2668-3a38fdb5de98",
  "command": {
    "_ObjectType": "AbortCommand",    
    "reference_id": "4185027f-0574-6f55-2668-3a38fdb5de98",
    "abort_message": "abort message"
  }
}

AbortCommand Response

{
  "_ObjectType": "CommandResponseObject",
  "status": "success",
  "cid": "12ce83f6-6d18-0d6e-08b6-c00fdbbf085a"
}


Payment Sequences


This section describes the expected sequences in P2M scenarios. Each scenario is expressed using a sequence of Sender / Receiver functionality.

Reminder: Before this scenario starts, an exchange of a common payment identifier (Reference ID) must be completed.

Charge Sequence

Step Command Type Triggered by Description
1 GetInfoCommand Sender The wallet requests payment details using the reference id provided. The receiver will respond with the payment details and merchant data. The wallet will display the payment details so the customer can approve or reject
2 InitChargeCommand Sender Following customer approval the wallet initializes the payment process and sends the payer data
3 ReadyForSettlementNotification Sender The wallet indicates the payment is ready for settlement. The wallet is expected to submit a transaction on-chain immediately before or after this step

Charge Sequence Diagram

Charge Sequence Diagram

Authorization Sequence (Auth / Capture)

Step Command Type Triggered by Description
1 GetInfoCommand Sender The wallet requests payment details using the reference id provided. The receiver will respond with the payment details and merchant data. The wallet will display the payment details so the customer can approve or reject
2 InitAuthorizeCommand Sender Following customer approval the wallet initializes the payment process and sends the payer data
3 AuthorizedNotification Sender The wallet indicates the funds are locked for a future capture

Authorization Sequence Diagram

Authorize Sequence Diagram

Capture Sequence (Auth / Capture)

IMPORTANT: Successful authorization is a precondition to capture

Step Command Type Triggered by Description
1 CaptureCommand Receiver The receiver requests to capture the authorized funds or part of it
2 ReadyForSettlementNotification Sender The wallet indicates the payment is ready for settlement. The wallet is expected to submit a transaction on-chain immediately before or after this step

Capture Sequence Diagram

Capture Sequence Diagram

Void Sequence (Auth / Capture)

IMPORTANT: Successful authorization is a precondition to void

Step Command Type Triggered by Description
1 VoidCommand Receiver Receiving VASP wants to void the payment. For example, the merchant voided the payment because the purchased products are out of stock

Risk Checks Failed (Init Payment Error)

Step Command Type Triggered by Description
1 GetInfoCommand Sender The wallet requests payment details using the reference id provided. The receiver will respond with the payment details and merchant data. The wallet will display the payment details so the customer can approve or reject
2 InitChargeCommand / InitAuthorizeCommand Sender Following customer approval the wallet initializes the payment process and sends the payer data. Risk checks failed. Receiver will respond with PaymentCommandErrorObject where the error_code is risk_checks_failed

Invalid Command Type (Premature Capture Attempt Error)

Step Command Type Triggered by Description
1 GetInfoCommand Sender The wallet requests payment details using the reference id provided. The receiver will respond with the payment details and merchant data. The wallet will display the payment details so the customer can approve or reject
2 CaptureCommand Sender Instead of initializing the payment, the wallet wrongly attempts to capture the payment. Receiver will respond with PaymentCommandErrorObject where the error_code is invalid_command_type

Payment Type Mismatch (Init Payment Error)

Step Command Type Triggered by Description
1 GetInfoCommand Sender The wallet requests payment details using the reference id provided. The receiver will respond with the charge payment details and merchant data. The wallet will display the payment details so the customer can approve or reject
2 InitAuthorizeCommand Sender Following customer approval the wallet attempts to initialize an auth payment. Receiver will respond with PaymentCommandErrorObject where the error_code is payment_type_mismatch

Abort Sequence - Customer Rejected the Payment Request

Step Command Type Triggered by Description
1 GetInfoCommand Sender The wallet requests payment details using the reference id provided. The receiver will respond with the payment details and merchant data. The wallet will display the payment details so the customer can approve or reject
2 AbortCommand Sender Customer decided not to approve the payment based on the information displayed. It is recommended to include a descriptive abort_message

Abort Sequence - Merchant Data Checks (performed by the Sender) Failed

Step Command Type Triggered by Description
1 GetInfoCommand Sender The wallet requests payment details using the reference id provided. The receiver will respond with the payment details and merchant data. The wallet will display the payment details so the customer can approve or reject
2 InitChargeCommand / InitAuthorizeCommand Sender Following customer approval the wallet initializes the payment process and sends the payer data
3 AbortCommand Sender Sender decided to abort. Can happen if the sender does not approve merchant data provided by the receiver

New Structures


This section introduces new structures required for P2M scenarios.

PaymentInfoObject

The minimal payment details required in order for the payer to decide whether to accept the payment or reject it.

Field Type Required? Description
receiver PaymentReceiverObject Y The details of the payment receiver (e.g. merchant)
action PaymentActionObject Y Information regarding the type of payment and payment amount
reference_id str Y Unique reference ID of this payment. This value should be globally unique
description str N Description of the payment. To be displayed to the customer
"payment_info": 
{
  "receiver": {
    PaymentReceiverObject()        
  },
  "action": {
    PaymentActionObject()
  },
  "reference_id": "4185027f-0574-6f55-2668-3a38fdb5de98",
  "description": "payment request description"     
}

PaymentReceiverObject

A PaymentReceiverObject represents the business/merchant in the payment. In P2M scenarios it is the receiver of funds.

Field Type Required? Description
account_address str Y Address of the receiver account. The addresses are encoded using bech32
business_data BusinessDataObject Y It includes the details of the merchant to be displayed to the payer
"receiver": {
  "account_address": "dm1pllhdmn9m42vcsamx24zrxgs3qqqpzg3ng32kvacapx5fl",         
  "business_data": {
    BusinessDataObject()
  }        
}

PaymentSenderObject

A PaymentSenderObject represents the person in the payment. In P2M scenarios it is the sender of funds.

Field Type Required? Description
account_address str Y Address of the receiver account. The addresses are encoded using bech32
payer_data PayerDataObject Y The details of the payer
"sender": {
  "account_address": "dm1pg9q5zs2pg9q5zs2pg9q5zs2pg9skzctpv9skzcg9kmwta",
  "payer_data": {
    PayerDataObject() 
  }          
}

PayerDataObject

The details of the payer. payer_data is the minimal set of payer information required by the merchant to perform risk checks and apply AML policies.

Field Type Required? Description
given_name str Y Legal given name of the payer
surname str Y Legal surname of the payer
address AddressObject Y Merchant's physical address information
national_id NationalIdObject N National ID information for payer. e.g. SSN
"payer_data": 
{
  "name": "Alice",
  "surname": "Cooper",
  "address": {
    AddressObject()
  },
  "national_id": {
    NationalIdObject()
  }        
}

BusinessDataObject

The details of the merchant.

Field Type Required? Description
name str Y Merchant's display name. Should be recognizable by the payer
legal_name str Y The legal entity name
image_url str N URL with the business logo
address AddressObject Y Merchant's physical address information
"business_data": 
{
  "name": "Acme",
  "legal_name": "Acme Technologies Inc.",
  "address": {
    AddressObject()
  }        
}

PaymentActionObject

Information about the payment type (i.e. action), amount and currency.

Field Type Required? Description
amount uint Y Amount of the transfer. Base units are the same as for on-chain transactions for this currency. For example, if DiemUSD is represented on-chain where "1" equals 1e-6 dollars, then "1" equals the same amount here. For any currency, the on-chain mapping must be used for amounts.
currency enum Y One of the supported on-chain currency types, e.g. XUS
action Action enum Y Populated in the request. This value indicates the requested action to perform. For immediate capture and P2P transfer, "charge" is used. For auth and capture, "auth" and "capture" should be used. "capture" can only be performed after a valid "auth"
valid_until uint N Unix timestamp indicating until when the payment can be authorized. Once this time has been reached, an attempt to authorize and lock the funds will be rejected. One should consider limiting this period to several minutes (e.g. 30 minutes) which should suffice for the customer to approve or reject the payment request
timestamp uint Y Unix timestamp indicating the time that the payment Command was created.
{
    "amount": 100000000,
    "currency": "XUS",
    "action": "auth",
    "valid_until": 74000,
    "timestamp": 72322,
}

Action Enum

The following values are allowed for the Action Enum

  • charge
  • auth
  • capture

AddressObject

Represents a physical address

Field Type Required? Description
city str Y The city, district, suburb, town, or village
country str Y Two-letter country code (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)
line1 str Y Address line 1
line2 str N Address line 2 - apartment, unit, etc.
postal_code str Y ZIP or postal code
state str N State, county, province, region.
{
    "city": "San Francisco",
    "country": "US",
    "line1": "1260 Market Street",
    "line2": "Suite 450",
    "postal_code": "94103",
    "state": "CA",
}

NationalIdObject

Represents a national ID.

Field Type Required? Description
id_value str Y Indicates the national ID value - for example, a social security number
country str N Two-letter country code (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)
type str N Indicates the type of the ID
{
    "id_value": "123-45-6789",
    "country": "US",
    "type": "SSN",
}

PaymentCommandErrorObject

This element is used to indicate that the command execution ended with an error. Successful command executions must NOT include this element.

Field Type Required? Description
error_code ErrorCode enum N This field is used to specify the reason for the error
error_message str N Additional details about this error
"payment_command_error": {
  "error_code": "reference_id_not_found",
  "error_message": "Payment reference id was not found"
}

This element can be added to any command response under the result object (if the command execution was not successful). For example, a response of GetInfoCommand in which the refernce_id provided was not found by the receiver:

{
  "_ObjectType": "CommandResponseObject",
  "status": "success",
  "cid": "12ce83f6-6d18-0d6e-08b6-c00fdbbf085a",
  "result": {
    "_ObjectType": "PaymentCommandErrorObject",
    "payment_command_error": {
      "error_code": "reference_id_not_found",
      "error_message": "Payment reference id was not found"
    }
  }
}

ErrorCode Enum

  • reference_id_not_found
  • risk_checks_failed
  • missing_information
  • payment_type_mismatch
  • invalid_command_type
  • unspecified_error

Appendix A - Prerequisite: Sharing Common Payment Identifier and Address

Note that this is a prerequisite for the off-chain negotiations and not a part of it.

Acquire Payment Identifier and Receiver Address Using Redirect URL

This URL contains the payment reference id (i.e. the common payment identifier) and the wallet's website address.

The redirect URL is likely to be used in the Web Redirect flow which means that the customer will be redirected from the merchant's checkout page to the wallet's website to review and approve the payment.

The table below specifies the fields that should be encoded into a series of URL parameters appended to the query string.

Field Type Required? Description
vasp_address str Y Address of receiving VASP. The address is encoded using bech32. For Diem addresses format, refer to the "account identifiers" section in DIP-5.
reference_id str Y A unique identifier of this payment. It should be a UUID according to RFC4122 with "-"'s included.
redirect_url str N Encoded URL used by the wallet to redirect the customer back to the merchant

For example, for the following values:

Field Value
vasp_address dm1pgxah7pxhzljvp3p4m9g0m3tm0qqqqqqqqqqqqqqgyftgh
reference_id ad8d888a-1791-4b63-98e5-6f1d6ddb4411
redirect_url http%3A%2F%2Fsomemerchantnname.com%2Fcallbackpage

The URL format would be:

https://some-diem-wallet.com/pay?vasp_address=dm1pgxah7pxhzljvp3p4m9g0m3tm0qqqqqqqqqqqqqqgyftgh&reference_id=ad8d888a-1791-4b63-98e5-6f1d6ddb4411&redirect_url=http%3A%2F%2Fsomemerchantnname.com%2Fcallbackpage

After parsing this request, the wallet can request the payment details from the receiving VASP and display them to the customer to review and approve.

Acquire Payment Identifier and Receiver Address Using QR Code

Similar to the URL, the QR code contains the payment reference id (i.e. the common payment identifier).

The QR Code is likely to be used in the QR Scan flow, which means that the customer will use the wallet app on the mobile device to scan the QR code on the merchant's checkout page. Following the QR code scan, the wallet app will display the payment details for the customer to review and approve the payment.

The QR code is a representation of a deeplink. The table below specifies the fields that should be encoded into the QR code deeplink.

Field Type Required? Description
vasp_address str Y Address of receiving VASP. The address is encoded using bech32. For Diem addresses format, refer to the "account identifiers" section in DIP-5.
reference_id str Y A unique identifier of this payment. It should be a UUID according to RFC4122 with "-"'s included.
redirect_url str N Encoded URL used by the wallet to redirect the customer back to the merchant

For example, for the following values:

Field Value
vasp_address dm1pgxah7pxhzljvp3p4m9g0m3tm0qqqqqqqqqqqqqqgyftgh
reference_id ad8d888a-1791-4b63-98e5-6f1d6ddb4411

The deeplink represented by QR code would be (the domain and path are examples - the real wallet domain/path should be used):

diem://some-diem-wallet.com/pay?vasp_address=dm1pgxah7pxhzljvp3p4m9g0m3tm0qqqqqqqqqqqqqqgyftgh&reference_id=ad8d888a-1791-4b63-98e5-6f1d6ddb4411

After scanning the QR code, the wallet can request the payment details from the receiving VASP and display them to the customer to review and approve.