# Open a Purchase

A card purchase for your end user, to the wallet the call names or to its default wallet of the pair's family.

## Overview

- `customerIp` is the end user's public IP address as your server saw it: the payment provider decides from it whether it can serve the user. A private, reserved or malformed address answers `400` `CARD_ONRAMP_CUSTOMER_IP_INVALID`.
- With `address`, the wallet is attested by this call and kept, not made the default. Without it, the default wallet of the pair's family is used; `409` `CARD_ONRAMP_WALLET_MISSING` when there is none.
- The answer carries `hostedLink` (send the user there, valid 30 minutes) and the client secret to embed the payment widget instead.
- The amount only suggests one: the user can change it, and the currency, in the widget. The session is locked to the wallet and the network.
- An `Idempotency-Key` answers `200` with the same session and a fresh link; the user's IP address is left out of the comparison.
- Every refusal before the payment provider is called writes nothing.

## Endpoint

### `POST /v1/ramp/card/customers/{externalId}/sessions`

Authentication: signed by the tenant's server — headers `x-tenant-api-key`, `x-timestamp`, `x-signature` (see Authentication → Tenant signature). No user token.

Opens a card purchase for the end user.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `externalId` | string | yes | Your own id of the end user, 1 to 100 characters: letters, digits, dot, underscore, colon, at sign or hyphen |

**Headers**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Idempotency-Key` | string | no | Up to 255 letters, digits, - or _; your order id for example |

**Request body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `pair` | string | yes | currency/network, one of the pairs your tenant offers |
| `customerIp` | string | yes | The end user public IPv4 or IPv6 address |
| `isTestnet` | boolean | no | true for the sandbox |
| `address` | string | no | The wallet of this purchase; the default wallet when omitted |
| `sourceAmount` | string | no | Suggested fiat amount, at most 2 decimals |
| `destinationAmount` | string | no | Suggested crypto amount, instead |
| `sourceCurrency` | string | no | eur or usd |
| `returnUrl` | string | no | Where the hosted page sends the user back; one your tenant allows |
| `locale` | string | no | en or it |
| `theme` | string | no | light or dark |

**Responses**

`201` Created

```json
{
  "session": {
    "id": "1a9f1da0-40b0-4b90-b33c-ddf9d31922d1",
    "environment": "sandbox",
    "status": "initialized",
    "providerStatus": "initialized",
    "providerSessionId": "cos_test000001",
    "pair": {
      "name": "usdc/base",
      "currency": "usdc",
      "network": "base",
      "aureaChain": "base",
      "family": "evm",
      "sourceCurrencies": ["usd"]
    },
    "destination": {
      "kind": "tenant_wallet",
      "walletId": null,
      "addressId": null,
      "address": "0x2f8C1e4d6B3A9E0F7C5D2B1A8E6f4c3d0b9A7E51"
    },
    "customer": {
      "externalId": "user_8421"
    },
    "requested": {
      "sourceCurrency": "usd",
      "sourceAmount": "50.00",
      "destinationAmount": null
    },
    "amounts": {
      "sourceCurrency": "usd",
      "sourceAmount": "50.00",
      "destinationAmount": null,
      "networkFee": null,
      "transactionFee": null
    },
    "transactionId": null,
    "failureCode": null,
    "createdAt": "2026-09-25T01:46:56.634Z",
    "updatedAt": "2026-09-25T01:46:56.663Z"
  },
  "clientSecret": "cos_test000001_secret_standin1",
  "publishableKey": "pk_test_51StandInPublishable0000",
  "hostedLink": {
    "url": "https://api.aureahub.com/v1/ramp/card/hosted#UF5gTU_QTII1iZrx9S6LoMtntQydBcASR6xG8AzhE90",
    "expiresAt": "2026-09-25T02:16:56.670Z"
  }
}
```

`409` No wallet

```json
{
  "statusCode": 409,
  "error": "ConflictError",
  "message": "This end user has no default evm wallet in sandbox: name the wallet with address, or attest a default one first.",
  "details": {
    "code": "CARD_ONRAMP_WALLET_MISSING",
    "family": "evm",
    "environment": "sandbox"
  }
}
```

`400` Not a public IP

```json
{
  "statusCode": 400,
  "error": "BadRequestError",
  "message": "customerIp is the end user's public IPv4 or IPv6 address: the payment provider decides from it whether it can serve the user",
  "details": {
    "code": "CARD_ONRAMP_CUSTOMER_IP_INVALID"
  }
}
```

---

Web version: https://docs.aureahub.com/#card-wallets-session-create
