10.64. DD 64: Algorithm for transactions with KYC checks#

10.64.1. Summary#

This design document specifies the algorithm that wallets and merchants should use for processing and (re-)trying transactions where KYC checks may apply.

10.64.2. Motivation#

The exchange requires the customer to pass KYC checks and satisfy AML rules for various transactions. However, the corresponding rules are dynamic and may also be hidden from the client for regulatory purposes.

10.64.3. Requirements#

  • Minimize the time time the user has to wait (=> long-poll efficiently)

  • Minimize the number of requests that the exchange has do process (=> do not quickly retry when it’s clear the the request is unlikely to succeed now)

10.64.4. Proposed Solution#

Steps for processing operation of type op and amount amt:

  1. Initialize last_op_attempt := null, last_rule_gen := null and last_aml_review := false and all back-off values to 0.

  2. Check if a zero limit for op is applicable.

    • If the zero limit denies op, proceed with step 3.

    • Proceed with step 2.

  3. Attempt to make a request for op at the exchange. If the /kyc-check/ result did not change since the last attempt, make sure to use exponential backoff on op requests with the frequency increasing up to once per day. The exponential backoff should be reset to 0 if the /kyc-check/ result changed in any way. Set last_op_attempt to the current time.

    • If the request succeeds, halt.

    • If last_aml_review was true, proceed with step 6.

    • If last_rule_gen is not null (Note 1), proceed with step 5.

    • Proceed with step 3.

  4. Request the /kyc-check/... endpoint applicable for op (without long-polling!).

    • Handle response as detailed in step 7.

  5. Request the /kyc-check/... endpoint applicable for op with long-polling for lpt=1.

    • While waiting for the response, prompt the user to perform KYC auth wire transfer.

    • Handle response as detailed in step 7.

  6. Request the /kyc-check/... endpoint applicable for op with long-polling for min_rule set to last_rule_gen.

    • While waiting for the response, prompt the user to provide KYC information.

    • Handle response as detailed in step 7.

  7. Request the /kyc-check/... endpoint applicable for op with long-polling for lpt=2 and, additionally min_rule set to the last last_rule_gen (if the latter is not null).

    • While waiting, indicate to the user that we are waiting on the provider’s staff to review our account.

    • Handle response as detailed in step 7.

  8. General handling of /kyc-check responses:

    • If the request returns 409 Conflict, proceed with step 4.

    • If the request returns 404 Not found, proceed with step 8 applying the exposed default rules of the exchange.

    • If the request returns 403 Forbidden, check if the private key for the indicated public key is available, if so try again with that private key, otherwise proceed with step 4.

    • If the request returns 204 No Content: * Set last_aml_review := false. * Proceed with step 2.

    • If the request returns 202 Accepted:

      • Set last_aml_review := response.aml_review.

      • Set last_rule_gen := response.rule_gen.

      • If the exposed limits do not explicitly deny op, proceed with step 2.

      • Otherwise, proceed with step 5.

    • If the request returns 200 Ok:

      • Set last_aml_review := response.aml_review.

      • Set last_rule_gen := response.rule_gen.

      • Handle exposed limits returned in step 8.

    • If the response indicates no change in the status (including when there was no response because the connection was closed):

      • Repeat the request, using exponential back-off to reduce check frequency (without even long-polling) to eventually only check once per day.

      • Ensure the long-polling interval specified in the request works with the middleware. If we detect that a request timed out before the specified long-polling interval, use a shorter timeout argument in the HTTP request the next time (but do still keep exponentially backing off the actual request frequency).

      • Lower the back-off to zero if:

        • the user manually reviews the KYC auth wire transfer instructions, or

        • the user manually reviews KYC information page instructions, or

        • if op is a deposit and lpt=1 and a withdraw succeeded from the same account

  9. Handle exposed limits applicable to the account:

    • If the exposed limits do not deny op, proceed with step 2.

    • Otherwise (the exposed limits do deny op), show an error message indicating that the operation is forbidden due to legal restrictions on the payment service provider.

    • If merely a threshold over some timeframe is currently violated, compute the time when the operation may be allowed again, indicate that to the user, allowing them to “retry immediately” anyway, and also go to step 2 automatically at that time.

10.64.4.1. Notes:#

  • Note 1: We must long-poll for the next rule generation here, since we can assume that the current set of rules contains non-exposed rule that prevents the current operation.

10.64.5. Definition of Done#

N/A

10.64.6. Alternatives#

N/A

10.64.7. Drawbacks#

N/A

10.64.8. Discussion / Q&A#

(This should be filled in with results from discussions on mailing lists / personal communication.)