Cross-border Supporting Documents

Upload, replace, submit, and resolve supporting documents before collecting funds.

Request creation returns requiredDocuments for the receiver currency, beneficiary country, and payout method. Build your upload UI from this response. A nonempty list starts at documents_required; an empty list starts at pending_charge. If request creation fails, resolve the error before continuing; do not assume documents are optional.

For CNY bank payouts, a Proforma Invoice or Contract satisfies the requirement. Alipay payouts do not require supporting documents. Always use the returned list rather than hardcoding requirements by currency.

Interpret the required groups

{
  "requiredDocuments": [
    {
      "anyOf": [
        {
          "type": "proforma_invoice",
          "name": "Proforma Invoice",
          "description": "Preliminary bill of sale."
        },
        {
          "type": "contract",
          "name": "Contract",
          "description": "Agreement between buyer and seller."
        }
      ]
    }
  ],
  "documents": []
}

Every group in requiredDocuments must be satisfied (AND). Within each group's anyOf, at least one document type must be present (OR). Uploading both alternatives is allowed. For example:

{
  "requiredDocuments": [
    {
      "anyOf": [
        {
          "type": "proforma_invoice",
          "name": "Proforma Invoice",
          "description": "Invoice."
        }
      ]
    },
    {
      "anyOf": [
        {
          "type": "contract",
          "name": "Contract",
          "description": "Agreement."
        }
      ]
    }
  ]
}

This second example requires both types. A group with alternatives alongside another single-type group requires one alternative and the single-type document. The current upload enum accepts proforma_invoice and contract. type identifies the document's purpose; the file MIME type identifies its format.

Upload or replace a document

Call POST /documents using multipart form data, with fields crossBorderRequestId, type, and one file. Paths are relative to https://api-v2.honeycoin.app/api/b2b/cross-border/requests or the sandbox equivalent.

curl --request POST 'https://api-v2.honeycoin.app/api/b2b/cross-border/requests/documents' \
  --header 'Authorization: Bearer YOUR_BEARER_TOKEN' \
  --form 'crossBorderRequestId=request_example_001' \
  --form 'type=proforma_invoice' \
  --form '[email protected];type=application/pdf'

Supported MIME types: application/pdf, image/jpeg, image/png, image/gif, image/webp, image/heic, image/heif. Each file must be nonempty and at most 10 MiB. The response returns its file ID in data.id.

The request response includes documents: [{type, fileId, uploadedAt}], where uploadedAt is Unix milliseconds. Uploading another file of the same type replaces the document used for that type; a different type adds another entry. Use the latest returned file ID when displaying the request’s documents. There is no document-delete endpoint in this API.

Uploads are allowed only in documents_required or documents_rejected. Uploading does not submit for review or change the status, even when all groups are satisfied.

Explicitly submit for review

Call POST /documents/submit with JSON:

{
  "crossBorderRequestId": "request_example_001"
}

If any required group is missing, the API returns 422 MISSING_DOCUMENTS. Otherwise it returns success: true and moves the request to documents_submitted. There is no finalSubmission boolean. Customers cannot upload replacements while a submission is under review.

Production review is performed by HoneyCoin. Approval uses the exact status documents_approved, then the system advances to pending_charge. Initiate the charge only once the current status is pending_charge and the customer has confirmed the quote. Document submission or approval does not itself collect funds.

Rejection and resubmission

A rejection leaves the request at documents_rejected. Read rejectionReason on the request or the crossborder_updated event. Upload the corrected file with the same type, then explicitly submit again. There is no automatic reset to documents_required, and uploading alone does not trigger another review.

If submission times out, fetch the request before retrying. In production, documents_submitted means review is already in progress. In sandbox, the submit endpoint also accepts that state so a failed simulated outcome can be retried. Display rejectionReason as the current review result only while the status is documents_rejected.

See sandbox testing for customer-controlled approval and rejection outcomes. outcome is sandbox-only and must not be sent to production.

See Cross-border Enums for display titles and exact supporting document types.