# On-Off Ramp

## Supported Stablecoins

<table><thead><tr><th>Stablecoin</th><th width="100.3333740234375">Network</th><th>Ramp type</th><th>Network fee*</th></tr></thead><tbody><tr><td><strong>CUSD / USDC / USDT</strong></td><td>CELO</td><td>On-ramp &#x26; Off-ramp</td><td>$0.01</td></tr><tr><td><strong>USDC</strong></td><td>OP</td><td>On-ramp &#x26; Off-ramp</td><td>$0.15</td></tr><tr><td><strong>USDC</strong></td><td>BASE</td><td>On-ramp &#x26; Off-ramp</td><td>$0.10</td></tr><tr><td><strong>USDC</strong></td><td>MATIC</td><td>Off-ramp only</td><td>$0.30</td></tr><tr><td><strong>USDC</strong></td><td>SOL</td><td>Off-ramp only</td><td>$0.50</td></tr></tbody></table>

\* Network fees are deducted from the customer’s payout.

***

## Getting Started

All you need is a **public API key**.\
Create one by following the [authentication guide](https://docs.cashramp.co/cashramp/introduction/authentication).

The ramp is delivered as a URL you build with query parameters.

### Base URLs

<table><thead><tr><th width="160.6666259765625">Environment</th><th>URL</th></tr></thead><tbody><tr><td><strong>Staging</strong></td><td><code>https://staging.useaccrue.com/hosted/ramp</code></td></tr><tr><td><strong>Production</strong></td><td><code>https://useaccrue.com/hosted/ramp</code></td></tr></tbody></table>

### URL Parameters

<table><thead><tr><th width="176.77777099609375">Name</th><th width="93.8887939453125">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>key</code></td><td><strong>Yes</strong></td><td>Your public API key.</td></tr><tr><td><code>paymentType</code></td><td><strong>Yes</strong></td><td><code>deposit</code> or <code>withdrawal</code>.</td></tr><tr><td><code>address</code></td><td>No</td><td>Wallet to receive funds. If omitted, Cashramp tries <code>window.ethereum</code>.</td></tr><tr><td><code>coin</code></td><td><strong>Yes</strong></td><td>Stablecoin symbol (see table above).</td></tr><tr><td><code>network</code></td><td><strong>Yes</strong></td><td>Network name from the table.</td></tr><tr><td><code>amount</code></td><td>No</td><td>Quantity of the stablecoin.</td></tr><tr><td><code>reference</code></td><td>No</td><td>Your idempotent reference.</td></tr><tr><td><code>redirectUrl</code></td><td>No</td><td>Where to send the user after completion.</td></tr><tr><td><code>currency</code></td><td>No</td><td>ISO-4217 fiat code (e.g., <code>USD</code>).</td></tr><tr><td><code>phone</code></td><td>No</td><td>Customer’s phone number.</td></tr><tr><td><code>hideAddress</code></td><td>No</td><td><code>true</code> to hide the wallet address field.</td></tr><tr><td><code>isWalletContext</code></td><td>No</td><td>Set <code>false</code> to ignore <code>window.ethereum</code> and use your own flow. Default <code>true</code>.</td></tr></tbody></table>

{% code title="Example" overflow="wrap" %}

```url
https://useaccrue.com/hosted/ramp?key=CSHRMP-PUBK_mO86nN3ye84hIso&paymentType=deposit&coin=CUSD&network=CELO&amount=10&reference=test_reference
```

{% endcode %}

***

## Custom Crypto-Deposit Flow

When `window.ethereum` is present, Cashramp prompts the user to sign the transfer automatically.\
If it isn’t, we emit a `postMessage` so you can run your own UX:

```javascript
window.addEventListener("message", (event) => {
  if (event.origin === "https://useaccrue.com") {
    const { event: name, payload } = event.data;
    if (name === "crypto.requested") {
      const amountUsd = Number(payload.amountCents) / 100;
      const destination = payload.destinationAddress;
      const paymentRequestId = payload.paymentRequest;

      /*
       * Launch your custom flow to send EXACTLY
       * `amountUsd` worth of stablecoins to `destination`.
       * After broadcasting, call confirmTransaction (below).
       */
    }
  }
});
```

***

## Confirm Transaction

After broadcasting the transfer, poll `confirmTransaction` until it settles.\
Poll in line with block times: CELO & Optimism ≈ 10 s; Ethereum ≈ 60 s.

{% code overflow="wrap" %}

```graphql
mutation {
  confirmTransaction(
    paymentRequest: "VHlwZXM6OkNhc2hyYW1wOjpBUEk6Ok1lcmN6YW50UGF5bWVudFJlcXVlc3QtZjVkZDdhYWEtZDI1Yy00YTZmLTkwODMtNzk1NjdkOTNjNmM4"
    transactionHash: "0x4321897b3c4495a314d081dbcf2cb5310b19834bda124f5ad03e07464b1add73"
  )
}
```

{% endcode %}

<table><thead><tr><th width="187.33331298828125">Argument</th><th>Description</th></tr></thead><tbody><tr><td><code>paymentRequest</code></td><td>Global ID from the earlier <code>crypto.requested</code> payload.</td></tr><tr><td><code>transactionHash</code></td><td>Hash of your on-chain transfer.</td></tr></tbody></table>

### What Happens Next

* The payment request moves from `pending_funding` → `created`.
* A webhook fires with the updated status.
* Cashramp emails the user a link to withdraw the fiat equivalent.

***
