Manual release flow

In the customer offramp process, it is the merchant’s responsibility to ensure that the balance deduction logic is implemented correctly and is secure against potential misuse by customers. However, we also provide an optional enhanced flow that simplifies the integration by introducing a “release” step.

sequenceDiagram
    Merchant->>Breeze Offramp Service: (1) API call: Create offramp request(releaseMethod: manual)
    Breeze Offramp Service->>Merchant: (1') Return offramp URL
    Breeze Offramp Service->>Merchant: (2) Redirect User to Offramp URL
    Breeze Offramp Service-->>+Merchant: (3) Webhook notification: REQUIRES_RELEASE
    critical protect this logic with lock
    option Customer balance is sufficient
        Merchant->>Breeze Offramp Service: API Call: Release the fund
    option Customer balance is insufficient
        Merchant->>Breeze Offramp Service: API Call: Cancel offramp
    end
    Breeze Offramp Service-->>Merchant: (4) Webhook notification for status updates

Example Scenario

  • The user has a balance of $100 and requests to offramp $80.
  • You create an offramp request for $80, without deducting the balance in your system yet.
  • At this point, the user’s balance in your system remains $100.
  • Breeze tell you the the offramp is now pending for release.
  • You deduct the customer's balance by $80 and tell Breeze to release the fund.
  • Breeze continue to process the offramp.

Workflow Steps

  1. Create an offramp request with the "manual release" flag(see the request sample below)
  2. Redirect the customer to the offramp page which is hosted by Breeze.
  3. When your server receives a REQUIRES_RELEASE webhook(see offramp events, run the check-release logic on your backend:
    1. If the customer has enough balance, deduct the balance and call the release API.
    2. otherwise call the cancel API.

Important

Ensure your release handling logic is atomic to avoid race conditions or concurrent issues.

API requests

Create offramp with manual release

curl -X POST 'https://api.breeze.cash/v1/offramp' \
  -u "YOUR_API_KEY:" \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "network": "polygon",
    "token": "usdc",
    "amount": 5000,
    "clientReferenceId": "offramp-<your-unique-id>",
    "email": "[email protected]",
    "successReturnUrl": "https://your-domain.com/offramp-complete",
    "failReturnUrl": "https://your-domain.com/offramp-aborted",
    "customer": {
      "country": "US"
      },
    "settings": { 
      "releaseMethod": "manual"
    }
  }'

A successful response will look like this:

Offramp Release

Use this to release the fund for offramps that are created with releaseMethod: manual.

  • Breeze will reject the release request if the offramp status is not REQUIRES_RELEASE.
curl -X POST 'https://api.breeze.cash/v1/offramp/ofrprq_abc123xyz/release' \
  -u "YOUR_API_KEY:" \
  --header 'Content-Type: application/json'

Successful response

{
  "status": "SUCCEEDED",
  "data": {
    "id": "ofrprq_abc123xyz",
    "status": "PENDING_DEPOSIT_CRYPTO_MERCHANT"
  }
}

Error responses

{  
  "status": "FAILED",  
  "errorCode": "OFFRAMP_CANNOT_RELEASE",
  "errorMessage": "<more-detailed-error-message>"
}