# didpay brainstorming ```javascript= { "metadata": { "from": "did:ex:alice", "to": "did:ex:pfi", "kind": "rfq", "id": "abcd123" "threadId": <RFQ_ID>, "parentId": null, "dateCreated": "ISO_8601" }, "data": { "offeringId": <OFFERING_ID>, "quoteAmountSubunits": "STR_VALUE", "credentials": <PRESENTATION_SUBMISSION_HASH>, "payinMethod": { "kind": "BTC_ADDRESS", "paymentDetails": <OBJ_HASH> }, "payoutMethod": { "kind": "MOMO_MPESA", "paymentDetails": <OBJ_HASH> } }, "signature": "COMPACT_JWS", "private": { "credentials": <PRESENTATION_SUBMISSION>, "payinMethod": { "paymentDetails": <OBJ> }, "payoutMethod": { "paymentDetails": <OBJ> } } } // now do Quote { metadata: { from: "did:ex:alice", to: "did:ex:pfi", kind: "rfq", id: "abcd123" threadId: <RFQ_ID>, parentId: <RFQ_ID>, dateCreated: "ISO_8601" }, data: { expiryTime: 'string' base: { currencyCode: 'string' amountSubunits: 'string' feeSubunits?: 'string' } quote: { currencyCode: 'string' amountSubunits: 'string' feeSubunits?: 'string' } }, signature: "COMPACT_JWS", } ``` when these above tbdex messages come back via GET /threads?threadId=1, they won't have the fields in `private` object, which means we don't get access to - sender name - recipient name - recipient bank account number (show the last 4 digits, obfuscate the rest) - decided this wasn't necessary but, we'd like to be able to access these fields. we _could_ save them in didpay, but these fields are considered dsl 3 and they need encryption at rest :::success WE ARE IGNORING DSL CONCERNS FOR DIDPAY! YAY!!!! Gonna put in sender full name in credential_applications and recipient full name in user_threads ::: ## "Offering" DIDPay BE -> DIDPay FE ```javascript= { offeringId: 'offering-123', country: 'KE', // look at quoteCurrency.currencyCode and just correlate to country code baseCurrency: { currencyCode : 'BTC', minSubunits : '1000', maxSubunits : '100000000' }, quoteCurrency: { currencyCode : 'KES', minSubunits : '1000', maxSubunits : '1000' }, // not necessary to send in payinMethods since there's only 1 - DIDPAY_BALANCE. frontend will hardcode fee payoutMethods: [ // will have an array of payoutMethods, not an array of Offerings (only 1) - look up YC PFI spec { kind : 'MOMO_MPESA', requiredPaymentDetails : momoPayoutSchema, feeSubunits : '1000' }, { kind : 'MOMO_OTHER_PHONE_COMPANY', requiredPaymentDetails : momoPayoutSchema, feeSubunits : '1000' }, { kind : 'BANK_FIRSTBANK', requiredPaymentDetails : bankPayoutSchema, }] } ``` ## "RFQ" DIDPay FE is sending in for `POST /transactions` ```javascript= // can use the same Rfq interface from tbdex-protocol // but extend it so vcs field is nullable? // REQUEST { offeringId: 'offering-123', quoteAmountSubunits: '500', // don't need payinMethod - backend just uses DIDPAY_BALANCE recipient: { firstName: 'Joe', lastName: 'Shmoe', dob: '01/01/1970', countryOfCitizenship: 'KE' } payoutMethod: { kind: 'MOMO_MPESA', paymentDetails: { accountHolderName: 'Joe Shmoe', accountNumber: '1234567890', accountProviderName: 'MPESA' // where do we use this? } } } // RESPONSE no body, just 202 ``` ## DIDPay FE renders all transactions `GET /transactions` steps to talk to YC PFI to render this array of txns 1. `SELECT * from failed_recipient_sanctions_transactions` 2. `SELECT thread_id from user_threads` 3. GET /threads?threadIds={thread_ids} 4. ^ returns [rfq, quote, order, orderstatus, orderstatus] 5. Combine the two data sources & translate into standard `transaction` data model --- 1. `GET /transactions` 2. poll `GET /transactions?ids={all of the non-completed txs}` (status < 500) Statuses - `RECIPIENT_FAILED_SANCTIONS` = 100 - BE: `failed_recipient_sanctions_transactions` table - `RFQ_SUBMITTED` = 200 - `QUOTE` = 300 - `ORDER_SUBMITTED` = 400 - `ORDER_COMPLETED` = 500 - `ORDER_REJECTED` = 600 - todo: what if YC submits a "close" (which is to say, they reject the transaction) -- probably out of scope ```javascript= [{ id: "", createdTime: "{ISO ts}", status: "{status}", firstName: "", lastName: "", amount: 5.00, deliveryMethod: "", expirationTime?: "{ISO ts}" // only on the quote }] ``` ### ^ can be used to then send in `GET /transactions?id={ids}`, use same endpoint to return same response ## Alice rejects a Quote or accepts a Quote `PUT /transactions/:id?action={accept|reject}` - accept: Send an Order - reject: Send a Close :warning: make sure YC PFI can accommodate this endpoint where we're only sending in a threadId like `PUT /threads/:id?messageType=order|close` Response: 202 ## Passing the `userId` in requests Proposal: HTTP Header `DIDPAY_USER_ID: ${}` Authentication? nope Are we going to be on the public internet? if so, maybe API key would suffice # q&a - When will we take in receiver’s PII? - during RFQ - If Alice onboards first and then sends Bob’s PII during RFQ, the flow to get Bob sanction checked will "feel" sync but will use the same async flow we used to onboard Alice. - :warning: if we make this step _feel_ sync, we're ignoring the case where Bob's sanction screen result needs manual intervention by a compliance officer - How will DIDPay store VC with PII? - DIDPay won't store VC. we'll always go get it from tbdiligence - country of citizenship for recipient - country of residency for sender