Instruments
An instrument is a reusable NETOPIA Payments token captured after verified hosted 0 RON enrollment.
Start POST /v1/enrollments with { "customer_id": "<ULID>" } (202), poll
GET /v1/enrollments/:id and redirect the customer to checkout_url. Pass an optional return_url: after hosted checkout the customer comes back through Payware and is redirected there (with enrollment_id appended; the return is not proof of success, wait for the enrollment.updated/instrument.attached webhooks or poll the enrollment). Wait for
succeeded and instrument_id before remote MIT billing. Payware never handles raw card
numbers or returns the token. See states, security, examples and recovery.
Raw token import below is mock-only; remote modes return 400 instrument_enrollment_required.
type is card, account or wallet; card details are present only for type: "card" (otherwise null).
Instrument responses include nullable enrollment_verified_at; remote billing requires it.
| Method & path | Description |
|---|---|
POST /v1/instruments | Mock-only token import |
GET /v1/instruments/:id | Retrieve |
GET /v1/customers/:id/instruments | List a customer's instruments |
DELETE /v1/instruments/:id | Detach (soft delete; past charges keep referencing it) |
| Field | Type | Required | Notes |
|---|---|---|---|
customer_id | ULID | yes | |
netopia_token | string | yes | |
type | card | account | wallet | no | default card; hosted enrollment always produces card |
card_last4 | 4 chars | no | display only |
card_brand | string (≤20) | no | display only |
card_exp_month / card_exp_year | integers | no | display only |
is_default | boolean | no | the customer's first instrument is default automatically; setting true demotes the previous default |
{ "object":"instrument", "id":"01…", "customer_id":"01…", "type":"card",
"card":{"last4":"4242","brand":"visa","exp_month":12,"exp_year":2030},
"is_default":true, "created_at":"…" }
Detaching the instrument used by live subscriptions (trialing, active, past_due, paused)
switches them to the customer's oldest remaining instrument; if none exists the call fails with
409 instrument_in_use. Events: instrument.attached, instrument.detached.