BillingVibesCharge billing.vibes-charge@1
Generated at from
openvibe-contracts v0.419.0 and
openvibe-sdk v0.161.0.
- Version
- 1.0.0
- Owner
- billing
- Visibility
- public
- Status
- active
- Compatibility
- backward
- Schema
https://openvibe.network/contracts/billing/vibes-charge.v1.json
billing.vibes-charge@1: one Vibes Pay charge (D12). An app creates it for a person to pay with Vibes; GET /api/v1/vibes/charges/:id answers it, and a replay of the same app reference returns the same charge. amount is a whole number of Vibes (never a fraction, never nano-USD). status moves pending -> paid -> refunded, or pending -> expired|cancelled. sandbox charges use test Vibes only, worth nothing. The paid and refunded webhook/event payloads carry the same fields plus an opaque payer_ref and no person id or email.
Fields
| Field | Type | Required | Description | Constraints |
|---|---|---|---|---|
id | string | yes | ULID charge id. |
|
app | string | yes | The app that created the charge (its app_ id). |
|
project_id | string | yes | The app's project; paid Vibes land in that project's Vibes wallet. |
|
amount | integer | yes | Price in whole Vibes. A positive integer; Vibes have no fractions. |
|
description | string | yes | What the person is paying for. |
|
reference | string | yes | The app's own reference for this charge. It is the idempotency key: a replay with the same reference returns the same charge. |
|
status | enum | yes |
| |
pay_url | string | yes | OpenVibe's pay sheet for this charge, e.g. https://openvibe.network/pay/vch_... |
|
return_url | string | null | yes | Where the browser returns after paying; null when the app gave no return URL. |
|
created_at | string | yes |
| |
paid_at | string | null | yes | When the Vibes moved, or null while the charge is unpaid. |
|
refunded_at | string | null | yes | When the Vibes went back to the person, or null. |
|
expires_at | string | yes | The pay sheet stops accepting payment after this instant. |
|
sandbox | boolean | yes | True for a sandbox app: sandbox Vibes only, worth nothing. |
Examples
From the contract's own test fixtures: valid ones validate, rejected ones must fail.
Valid: expired
{
"id": "vch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"app": "app_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"project_id": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"amount": 50,
"description": "Sticker pack: Neon cats",
"reference": "order_123",
"status": "expired",
"pay_url": "https://openvibe.network/pay/vch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"return_url": "https://myapp.example/thanks",
"created_at": "2026-11-04T12:00:00.000Z",
"paid_at": null,
"refunded_at": null,
"expires_at": "2026-11-04T12:30:00.000Z",
"sandbox": false
}Valid: paid-sandbox
{
"id": "vch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"app": "app_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"project_id": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"amount": 50,
"description": "Sticker pack: Neon cats",
"reference": "order_123",
"status": "paid",
"pay_url": "https://openvibe.network/pay/vch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"return_url": null,
"created_at": "2026-11-04T12:00:00.000Z",
"paid_at": "2026-11-04T12:01:00.000Z",
"refunded_at": null,
"expires_at": "2026-11-04T12:30:00.000Z",
"sandbox": true
}Valid: pending
{
"id": "vch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"app": "app_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"project_id": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"amount": 50,
"description": "Sticker pack: Neon cats",
"reference": "order_123",
"status": "pending",
"pay_url": "https://openvibe.network/pay/vch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"return_url": "https://myapp.example/thanks",
"created_at": "2026-11-04T12:00:00.000Z",
"paid_at": null,
"refunded_at": null,
"expires_at": "2026-11-04T12:30:00.000Z",
"sandbox": false
}Valid: refunded
{
"id": "vch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"app": "app_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"project_id": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"amount": 50,
"description": "Sticker pack: Neon cats",
"reference": "order_123",
"status": "refunded",
"pay_url": "https://openvibe.network/pay/vch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"return_url": "https://myapp.example/thanks",
"created_at": "2026-11-04T12:00:00.000Z",
"paid_at": "2026-11-04T12:01:00.000Z",
"refunded_at": "2026-11-04T13:00:00.000Z",
"expires_at": "2026-11-04T12:30:00.000Z",
"sandbox": false
}Rejected: bad-id
{
"id": "vch_1",
"app": "app_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"project_id": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"amount": 50,
"description": "Sticker pack: Neon cats",
"reference": "order_123",
"status": "pending",
"pay_url": "https://openvibe.network/pay/vch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"return_url": "https://myapp.example/thanks",
"created_at": "2026-11-04T12:00:00.000Z",
"paid_at": null,
"refunded_at": null,
"expires_at": "2026-11-04T12:30:00.000Z",
"sandbox": false
}Rejected: description-too-long
{
"id": "vch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"app": "app_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"project_id": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"amount": 50,
"description": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"reference": "order_123",
"status": "pending",
"pay_url": "https://openvibe.network/pay/vch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"return_url": "https://myapp.example/thanks",
"created_at": "2026-11-04T12:00:00.000Z",
"paid_at": null,
"refunded_at": null,
"expires_at": "2026-11-04T12:30:00.000Z",
"sandbox": false
}Rejected: float-amount
{
"id": "vch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"app": "app_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"project_id": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"amount": 12.5,
"description": "Sticker pack: Neon cats",
"reference": "order_123",
"status": "pending",
"pay_url": "https://openvibe.network/pay/vch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"return_url": "https://myapp.example/thanks",
"created_at": "2026-11-04T12:00:00.000Z",
"paid_at": null,
"refunded_at": null,
"expires_at": "2026-11-04T12:30:00.000Z",
"sandbox": false
}Rejected: person-id
{
"id": "vch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"app": "app_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"project_id": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"amount": 50,
"description": "Sticker pack: Neon cats",
"reference": "order_123",
"status": "pending",
"pay_url": "https://openvibe.network/pay/vch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"return_url": "https://myapp.example/thanks",
"created_at": "2026-11-04T12:00:00.000Z",
"paid_at": null,
"refunded_at": null,
"expires_at": "2026-11-04T12:30:00.000Z",
"sandbox": false,
"user_id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
}Rejected: unknown-status
{
"id": "vch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"app": "app_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"project_id": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"amount": 50,
"description": "Sticker pack: Neon cats",
"reference": "order_123",
"status": "failed",
"pay_url": "https://openvibe.network/pay/vch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"return_url": "https://myapp.example/thanks",
"created_at": "2026-11-04T12:00:00.000Z",
"paid_at": null,
"refunded_at": null,
"expires_at": "2026-11-04T12:30:00.000Z",
"sandbox": false
}Rejected: zero-amount
{
"id": "vch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"app": "app_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"project_id": "prj_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"amount": 0,
"description": "Sticker pack: Neon cats",
"reference": "order_123",
"status": "pending",
"pay_url": "https://openvibe.network/pay/vch_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"return_url": "https://myapp.example/thanks",
"created_at": "2026-11-04T12:00:00.000Z",
"paid_at": null,
"refunded_at": null,
"expires_at": "2026-11-04T12:30:00.000Z",
"sandbox": false
}Validate
const contracts = require('openvibe-contracts');
contracts.validate('billing.vibes-charge@1', value); // { valid, errors: [{ path, message }] }