BEXO / Developers
BUILD WITH BEXO / INTEGRATION GUIDES

Sandbox identity guide

Exercise the identity contract in a controlled environment. Sandbox setup does not activate production billing, keys or access.

Reference edition 2026-10-19 • Selected public contract
sandboxtestingidentity API

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

  1. POST /identity/tenants to the isolated API with synthetic organization details.
  2. Store the one-time sandbox API key securely; it is not retrievable later from this response.
  3. Use verify:write to register a sandbox terminal, and members:write to create a sandbox plan.
  4. Use a controlled, properly created test membership and consent state. Direct identity/memberships activation is retired with HTTP 410.
  5. 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

CaseExpected handling
Missing / revoked credentialAuthentication failure; stop and correct credentials.
Wrong tenant terminalRejection; never substitute another tenant’s reader.
Expired or missing membershipA denied/nonverified result.
Missing or revoked consentNo assumption of continued disclosure permission.
Unavailable dependency / timeoutVisible recovery state; no automatic access grant.
Duplicate purchase retryOriginal Idempotency-Key retained; no second order.
Duplicate webhookDurable 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.

REQUEST / RESPONSE

Endpoint reference

Paths below include the API prefix. The OpenAPI server URL already includes /api.

POST/api/identity/tenants

Bootstrap 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.

Public accessHTTP 201Isolated sandbox

Request template

Set the API base to include /api. Replace path placeholders and prepare request.json from the body fields below before running.

shell
curl --fail-with-body -X POST "$BEXO_API_BASE/identity/tenants" \
  -H "Content-Type: application/json" \
  --data @request.json

Request body

FieldTypeDetails
legalNameRequiredstringSynthetic organization name for an isolated sandbox.
displayNameRequiredstringSandbox display name.
contactEmailRequiredstringControlled test email.

Example request body

json
{
  "legalName": "Example Test Organization",
  "displayName": "Example Sandbox",
  "contactEmail": "developer@example.com"
}

Response fields

FieldTypeDetails
tenantVendorSee the downloadable schema for nested fields.
apiKeyobjectSee the downloadable schema for nested fields.
View full machine-readable contract ↗
GET/api/identity/tenants/me

Read a sandbox tenant

Sandbox key with verify:read. Live environment keys are rejected by the sandbox-only gate.

Scoped integration keyHTTP 200Isolated sandbox

Request template

Set the API base to include /api. Replace path placeholders before running.

shell
curl --fail-with-body -X GET "$BEXO_API_BASE/identity/tenants/me" \
  -H "Authorization: Bearer $BEXO_INTEGRATION_KEY"

Response fields

FieldTypeDetails
tenantVendorSee the downloadable schema for nested fields.
View full machine-readable contract ↗
POST/api/identity/terminals

Register a sandbox terminal

Sandbox key with verify:write. label is required. serialNumber, devicePublicKey and firmwareVersion are optional.

Scoped integration keyHTTP 201Isolated sandbox

Request template

Set the API base to include /api. Replace path placeholders and prepare request.json from the body fields below before running.

shell
curl --fail-with-body -X POST "$BEXO_API_BASE/identity/terminals" \
  -H "Authorization: Bearer $BEXO_INTEGRATION_KEY" \
  -H "Content-Type: application/json" \
  --data @request.json

Request body

FieldTypeDetails
labelRequiredstringDevice label.
serialNumberstringOptional serial.
devicePublicKeystringOptional public key.
firmwareVersionstringOptional firmware version.

Response fields

FieldTypeDetails
terminalTerminalSee the downloadable schema for nested fields.
View full machine-readable contract ↗
POST/api/identity/plans

Create a sandbox plan

Sandbox key with members:write. This route prepares a plan; it does not create a paid membership.

Scoped integration keyHTTP 201Isolated sandbox

Request template

Set the API base to include /api. Replace path placeholders and prepare request.json from the body fields below before running.

shell
curl --fail-with-body -X POST "$BEXO_API_BASE/identity/plans" \
  -H "Authorization: Bearer $BEXO_INTEGRATION_KEY" \
  -H "Content-Type: application/json" \
  --data @request.json

Request body

FieldTypeDetails
nameRequiredstringPlan name.
durationDaysRequiredintegerDuration, 1–366 days.
pricePaiseRequiredintegerAmount in integer INR paise; 100 paise equals INR 1.
gracePeriodDaysintegerNonnegative grace period.
externalRefstringOptional external reference.

Response fields

FieldTypeDetails
planPlanSee the downloadable schema for nested fields.
View full machine-readable contract ↗
POST/api/identity/verify

Evaluate 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.

Scoped integration keyHTTP 200Isolated sandbox

Request template

Set the API base to include /api. Replace path placeholders and prepare request.json from the body fields below before running.

shell
curl --fail-with-body -X POST "$BEXO_API_BASE/identity/verify" \
  -H "Authorization: Bearer $BEXO_INTEGRATION_KEY" \
  -H "Content-Type: application/json" \
  --data @request.json

Request body

FieldTypeDetails
userIdstringTest member ID; or supply a valid cardToken.
cardTokenstringAlternative supported test card token.
terminalIdstringOptional nonrevoked terminal belonging to this tenant.
tenantPlanIdstringOptional plan filter.

Response fields

FieldTypeDetails
verifiedbooleanResult.
statusstringSandbox status.
ACTIVE · EXPIRED · NOT_FOUND · SUSPENDED
memberobjectSee the downloadable schema for nested fields.
subscriptionobjectSee the downloadable schema for nested fields.
eventIdstringAudit reference.
View full machine-readable contract ↗
POST/api/identity/memberships

Direct activation is retired

Sandbox direct activation returns 410. Use the approved checkout flow; never fabricate a payment to create an entitlement.

Scoped integration keyHTTP 410Isolated sandbox

Response fields

FieldTypeDetails
errorstringRetirement message.
View full machine-readable contract ↗
Build with a clear contract.

Configuration, approval and deployed behavior determine availability. Validate your own integration before release.

Review the launch checklist ↗

Reference source: b93a4d3 · Examples use synthetic data.