Confirm payment of a gift voucher purchase
Tell Shyni the money for a bank-transfer purchase has arrived: the voucher becomes
ACTIVE and its delivery mail goes to the buyer. Confirming an already ACTIVE
voucher is a harmless no-op that still answers 200 (no second mail). A purchase that
was cancelled, timed out or refunded answers 409 CONFLICT, and so does a purchase
paid by card through the gateway: that one is activated by the payment itself, and
confirming it by hand would let the studio collect the money twice. Confirming counts
the voucher value into this key's daily voucher cap exactly like issuing does; past the
cap it answers 422 API_KEY_DAILY_VOUCHER_CAP_EXCEEDED and the purchase stays unpaid.
Requires the vouchers:write scope, the studio's PRO tier, and an
Idempotency-Key header.
ApiKeyAuth vouchers:writeAuthorizationBearer <shyni_sk_live_*>An API key, issued once and never retrievable again: an organization key in the developer
portal, or a studio key in the studio's admin (Moje studio → API). Send as Authorization: Bearer shyni_sk_live_....
Scope: vouchers:write
code*stringIdempotency-Key*stringCaller-chosen idempotency token for this write. A retry under the SAME key with
the SAME body replays the first response; the SAME key with a DIFFERENT body is
422 IDEMPOTENCY_KEY_MISMATCH. See Idempotency above.
length <= 64The voucher, now ACTIVE.
application/json- response
id*stringInternal voucher id. /refund, /resend and /pdf key on code, not this id.
code*stringThe bearer code printed on the voucher and used to redeem it in a booking.
value*integerAmount in minor units of currency (hellers for CZK), the voucher face value.
int64remaining*integerUnspent balance in minor units of currency. An order draws only what it needs; the rest
stays on the same code until validUntil. 0 once the voucher is fully used.
int64currency*stringISO 4217 code of the studio currency the voucher is denominated in.
state*GiftVoucherState"CREATED""ACTIVE""USED""DEACTIVATED""PAYMENT_TIMEOUT""CANCELLED""REFUNDED"issuedVia*GiftVoucherIssuedViaHow the voucher was issued. API-issued vouchers are the only ones this API can refund (see /refund). IMPORT = brought over from another system by the studio data import.
"MANUAL""ONLINE""API""IMPORT"paidAt?|date-timevalidUntil*stringdatebuyer*billing?|nullmotif*GiftVoucherMotifPDF/print motif.
"CLASSIC""INK""LINES""CLEAN"dedication?string|nullnote?string|nullexternalRef?string|nullredeemedOrderId?|Set once the voucher has been applied to an order.
redeemedAt?|date-timeredemptions*array<>Every draw of this voucher that currently counts, oldest first. Draws reversed by a
cancelled order are not listed, so the amounts always sum to value - remaining.
Empty while nothing was drawn. redeemedOrderId/redeemedAt mirror the last item.
notification?|The outcome of a delivery mail THIS request asked for, non-null only on an
issue with notifyBuyer: true and on /resend. Every GET returns null:
Shyni does not store a voucher's delivery state.
createdAt*stringdate-timecurl -X POST 'https://api.shyni.io/api/v1/gift-vouchers/string/confirm-payment' \ -H 'Authorization: Bearer shyni_sk_test_YOUR_KEY' \ -H 'Idempotency-Key: 7f3c9a52-1d4e-4b86-a0c7-5e2b9d8f6a13'Response 200
The voucher, now ACTIVE.
{ "id": "string", "code": "string", "value": 0, "remaining": 0, "currency": "string", "state": "CREATED", "issuedVia": "MANUAL", "paidAt": "2019-08-24T14:15:22Z", "validUntil": "2019-08-24", "buyer": { "name": "string", "email": "user@example.com" }, "billing": { "company": "string", "ico": "string", "dic": "string", "address": "string" }, "motif": "CLASSIC", "dedication": "string", "note": "string", "externalRef": "string", "redeemedOrderId": "string", "redeemedAt": "2019-08-24T14:15:22Z", "redemptions": [ { "orderId": "string", "amount": 0, "redeemedAt": "2019-08-24T14:15:22Z" } ], "notification": "SENT", "createdAt": "2019-08-24T14:15:22Z"}Response 400
A parameter, header or request body is missing, malformed, or out of range. A request body property the endpoint does not define answers UNKNOWN_FIELD instead, with field naming it.
{ "code": "INVALID_INPUT", "message": "Parameter perPage must be between 1 and 100."}Response 401
Missing, malformed, unknown, or revoked API key (INVALID_API_KEY).
{ "code": "INVALID_API_KEY", "message": "Missing or invalid API key."}Response 403
The key is valid but the request is refused. Branch on code: INSUFFICIENT_SCOPE (the key lacks the
permission this endpoint requires), PLAN_REQUIRED (the studio is not on a plan that includes API keys,
Pro and above), ORIGIN_NOT_ALLOWED, SECRET_KEY_IN_BROWSER, or DEMO_STUDIO on a write to the demo studio.
See Authentication and Scopes above.
{ "code": "INSUFFICIENT_SCOPE", "message": "This API key does not have the permission this endpoint requires."}Response 404
The resource does not exist, or belongs to a different studio.
{ "code": "NOT_FOUND", "message": "Order not found."}Response 409
The request is well-formed but the studio's current state forbids it.
{ "code": "CONFLICT", "message": "The voucher cannot be deactivated because it is not active."}Response 422
Two causes share this status, branch on code: API_KEY_DAILY_VOUCHER_CAP_EXCEEDED
(this key's daily voucher cap is used up; the purchase stays unpaid) and
IDEMPOTENCY_KEY_MISMATCH (the Idempotency-Key was already used for a different
request, use a new key).
{ "code": "API_KEY_DAILY_VOUCHER_CAP_EXCEEDED", "message": "This API key has issued vouchers up to its daily cap. Retry tomorrow or ask the studio owner to raise the cap."}{ "code": "IDEMPOTENCY_KEY_MISMATCH", "message": "This Idempotency-Key was already used for a different request. Use a new key."}Response 429
Burst rate limit exceeded.
{ "code": "RATE_LIMITED", "message": "Too many requests. Retry after the time given in the Retry-After header."}