Sandbox identity guide
Exercise the identity contract in a controlled environment. Sandbox setup does not activate production billing, keys or access.
Use an isolated target
Agree a local/staging API, database and controlled test identities before running bootstrap operations. The examples below are documentation; no test tenant has been created by publishing this site. Do not copy sandbox bootstrap requests to the production host.
Bootstrap and prepare
- POST /identity/tenants to the isolated API with synthetic organization details.
- Store the one-time sandbox API key securely; it is not retrievable later from this response.
- Use verify:write to register a sandbox terminal, and members:write to create a sandbox plan.
- Use a controlled, properly created test membership and consent state. Direct identity/memberships activation is retired with HTTP 410.
- Call sandbox verify with the applicable user/card and optional plan/terminal filters.
Sandbox identity verification uses uppercase statuses. POS v1 returns a separate decision/reason contract. A live key is rejected by the sandbox-only gate even if the underlying tenant is approved.
A useful test matrix
| Case | Expected handling |
|---|---|
| Missing / revoked credential | Authentication failure; stop and correct credentials. |
| Wrong tenant terminal | Rejection; never substitute another tenant’s reader. |
| Expired or missing membership | A denied/nonverified result. |
| Missing or revoked consent | No assumption of continued disclosure permission. |
| Unavailable dependency / timeout | Visible recovery state; no automatic access grant. |
| Duplicate purchase retry | Original Idempotency-Key retained; no second order. |
| Duplicate webhook | Durable event-ID deduplication prevents repeated side effects. |
Use the integration checklist to capture actual results before production. A source route or successful build is not evidence that a payment/device journey worked.
Endpoint reference
Paths below include the API prefix. The OpenAPI server URL already includes /api.
/api/identity/tenantsBootstrap an isolated sandbox tenant
Use only an agreed isolated test deployment. Creates a sandbox_only tenant and returns a sandbox credential once. Store the key in a server-side secret store immediately. Does not issue live credentials or approve a vendor.
Request template
Set the API base to include /api. Replace path placeholders and prepare request.json from the body fields below before running.
curl --fail-with-body -X POST "$BEXO_API_BASE/identity/tenants" \
-H "Content-Type: application/json" \
--data @request.jsonRequest body
| Field | Type | Details |
|---|---|---|
legalNameRequired | string | Synthetic organization name for an isolated sandbox. |
displayNameRequired | string | Sandbox display name. |
contactEmailRequired | string | Controlled test email. |
Example request body
{
"legalName": "Example Test Organization",
"displayName": "Example Sandbox",
"contactEmail": "developer@example.com"
}Response fields
| Field | Type | Details |
|---|---|---|
tenant | Vendor | See the downloadable schema for nested fields. |
apiKey | object | See the downloadable schema for nested fields. |
/api/identity/tenants/meRead a sandbox tenant
Sandbox key with verify:read. Live environment keys are rejected by the sandbox-only gate.
Request template
Set the API base to include /api. Replace path placeholders before running.
curl --fail-with-body -X GET "$BEXO_API_BASE/identity/tenants/me" \
-H "Authorization: Bearer $BEXO_INTEGRATION_KEY"Response fields
| Field | Type | Details |
|---|---|---|
tenant | Vendor | See the downloadable schema for nested fields. |
/api/identity/terminalsRegister a sandbox terminal
Sandbox key with verify:write. label is required. serialNumber, devicePublicKey and firmwareVersion are optional.
Request template
Set the API base to include /api. Replace path placeholders and prepare request.json from the body fields below before running.
curl --fail-with-body -X POST "$BEXO_API_BASE/identity/terminals" \
-H "Authorization: Bearer $BEXO_INTEGRATION_KEY" \
-H "Content-Type: application/json" \
--data @request.jsonRequest body
| Field | Type | Details |
|---|---|---|
labelRequired | string | Device label. |
serialNumber | string | Optional serial. |
devicePublicKey | string | Optional public key. |
firmwareVersion | string | Optional firmware version. |
Response fields
| Field | Type | Details |
|---|---|---|
terminal | Terminal | See the downloadable schema for nested fields. |
/api/identity/plansCreate a sandbox plan
Sandbox key with members:write. This route prepares a plan; it does not create a paid membership.
Request template
Set the API base to include /api. Replace path placeholders and prepare request.json from the body fields below before running.
curl --fail-with-body -X POST "$BEXO_API_BASE/identity/plans" \
-H "Authorization: Bearer $BEXO_INTEGRATION_KEY" \
-H "Content-Type: application/json" \
--data @request.jsonRequest body
| Field | Type | Details |
|---|---|---|
nameRequired | string | Plan name. |
durationDaysRequired | integer | Duration, 1–366 days. |
pricePaiseRequired | integer | Amount in integer INR paise; 100 paise equals INR 1. |
gracePeriodDays | integer | Nonnegative grace period. |
externalRef | string | Optional external reference. |
Response fields
| Field | Type | Details |
|---|---|---|
plan | Plan | See the downloadable schema for nested fields. |
/api/identity/verifyEvaluate a sandbox membership
Sandbox key with verify:read. Supply userId or a supported cardToken and optional tenantPlanId/terminalId. Uses uppercase ACTIVE, EXPIRED, NOT_FOUND or SUSPENDED statuses. This contract is distinct from POS v1.
Request template
Set the API base to include /api. Replace path placeholders and prepare request.json from the body fields below before running.
curl --fail-with-body -X POST "$BEXO_API_BASE/identity/verify" \
-H "Authorization: Bearer $BEXO_INTEGRATION_KEY" \
-H "Content-Type: application/json" \
--data @request.jsonRequest body
| Field | Type | Details |
|---|---|---|
userId | string | Test member ID; or supply a valid cardToken. |
cardToken | string | Alternative supported test card token. |
terminalId | string | Optional nonrevoked terminal belonging to this tenant. |
tenantPlanId | string | Optional plan filter. |
Response fields
| Field | Type | Details |
|---|---|---|
verified | boolean | Result. |
status | string | Sandbox status.ACTIVE · EXPIRED · NOT_FOUND · SUSPENDED |
member | object | See the downloadable schema for nested fields. |
subscription | object | See the downloadable schema for nested fields. |
eventId | string | Audit reference. |
/api/identity/membershipsDirect activation is retired
Sandbox direct activation returns 410. Use the approved checkout flow; never fabricate a payment to create an entitlement.
Response fields
| Field | Type | Details |
|---|---|---|
error | string | Retirement message. |