# DIDPay API Spec ## Create Account - For onboarding Alice ### Endpoint: `POST /accounts` ### Request body ```javascript= { firstName: "Alice", lastName: "Jones", dob: "01/01/1970", country: "US" } ``` ### Response body 202 accepted ```javascript= { userId: "123" } ``` --- ## Get Account - For determining if Alice can have access to the main Activity/Remittance view ### Endpoint:`GET /accounts/:accountId` ### Request body none ### Response body 200 OK (no body) 401 Account not found (error message body) 403 Account sanctioned (error message body) --- ## Get Account Balance Return current 'omnibus' USD balance with YellowCard. Currently ignoring accountId because... it's not Alice's individual money. ### Endpoint: `GET /accounts/:accountId/balances` ### Request body none ### Response body ```javascript= { "available": 4723, "currency": "USD" } ``` --- ## Get Offerings - For rendering the available offerings in Remittance landing page, as well as rendering forms for field inputs for Alice to submit an RFQ ### Endpoint: `GET /offerings` ### Request body none ### Query Params In the future, this should support: - Source Currency - Target Currency - Country For Pigeon, we're just gonna return one Offering (in an array) relevant for Pigeon use case ### Response 200 OK ```javascript= [{ offeringId: 'offering-123', country: 'KE', baseCurrency: { currencyCode : 'BTC', minSubunits : '1000', maxSubunits : '100000000' }, quoteCurrency: { currencyCode : 'KES', minSubunits : '1000', maxSubunits : '1000' }, payoutMethods: [ { kind : 'MOMO_MPESA', requiredPaymentDetails : momoPayoutSchema, feeSubunits : '1000' },{ kind : 'BANK_FIRSTBANK', requiredPaymentDetails : bankPayoutSchema, }] }] ``` --- ## Get all exchanges' latest statuses - For Activity landing page, which lists all exchanges, render latest tbdex message in a user friendly way (RFQ submitted, Quote returned, OrderStatus returned) ### Endpoint: `GET /remittances/exchanges?ids={exchangeIds}` - for polling Quote and OrderStatus - for showing list of all transactions on the Activities landing page ### Query Params - id - i.e. `GET /remittances/exchanges?ids=1,2,3` ### Request body none ### Response body ```javascript= [{ id: "123", // exchangeId createdTime: "2023-04-01T12:12:12.000Z", status: { name: 'EX_REQUESTED, value: 110 }, firstName: "Alice", lastName: "Jones", amount: 5.00, // amount in QUOTE currency (i.e. BTC) !!! baseCurrencyCode: 'KES', quoteCurrencyCode: 'BTC', deliveryMethod: "MOMO_MPESA", expirationTime: "" // only on the quote }, { id: "125", createdTime: "2023-04-01T12:12:12.000Z", status: { name: 'EX_CANCELLED, value: 110 },, firstName: "Joe", lastName: "Schmoe", amount: 50.00, // amount in QUOTE currency (i.e. BTC) !!! baseCurrencyCode: 'KES', quoteCurrencyCode: 'BTC', deliveryMethod: "BANK_FIDELITY", expirationTime: "2023-04-02T12:15:000Z" }] ``` #### statuses - EX_REQUESTED = 100 (last message: RFQ) - EX_QUOTED = 110 (last message: Quote) - EX_SUBMITTED = 120 (last message: Order) - EX_PROCESSING = 130 (last message: OrderStatus) - EX_COMPLETED = 200 (last message: OrderStatus) - EX_REJECTED = 210 (last message: OrderStatus) - EX_CANCELLED = 300 (last message: Close) - ~~TX_REQUEST_FAILED_SANCTIONS = 300 (last message: RFQ)~~ :::warning TX_REQUEST_FAILED_SANCTIONS = 300 won't exist - DIDPay won't even send an RFQ if recipient fails sanction check ::: --- ## Create exchange - For sending an RFQ ### Endpoint: `POST /remittances/exchange` ### Request Body ```javascript= { offeringId: 'offering-123', quoteAmountSubunits: '500', recipient: { firstName: 'Joe', lastName: 'Shmoe', dob: '01/01/1970', country: 'KE' } payoutMethod: { kind: 'MOMO_MPESA', paymentDetails: { accountNumber: '1234567890', reason: 'no reason' } } } ``` ### Response 202 accepted 401 forbidden (if joe is sanctioned) :::warning - if joe is sanctioned, we don't create an RFQ message - so FE can't hit `GET /remittances/exchanges?ids={exchangeId}` ::: --- ## Update exchange - For cancelling RFQ, rejecting Quote or accepting Quote ### Endpoint: `PUT /remittances/exchanges/:id` - ~~After RFQ but _before_ Quote, Alice can only cancel RFQ~~ - After Quote but _before_ Order, Alice can either accept or reject Quote ### Request body ```javascript= { action: "accept|reject" } ``` :::warning how does DIDPay validate if this exchange at this point in time is allowed to send an Order, cancel RFQ, or close Quote? maybe we need to ask frontend to send us last message received - maybe not worry about this for the sake of time? ::: ### Response body 202 accepted 409 not allowed --- ## Error message format ```javascript= { errorMessage: 'o no!' } ```