Vouchers let you sell or grant access to products outside the regular checkout flow — for example in B2B deals, press promotions, or partner campaigns. Every voucher is linked to a Frisbii Media offer and, when redeemed, generates a regular order.
There are two redemption paths:
Direct redemption — for free offers, redeem server-side in one API call without a checkout UI
Checkout redemption — for paid or unknown offers, pass the voucher code through the normal checkout flow
Validate a voucher code
Validate a code before redeeming it to check its status and find out which offer it is linked to. This step is optional but useful for showing the customer what they are about to receive.
// @see https://api.frisbii-media-stage.com/#operation/validateVoucherCode
$response = json_decode($client->request('GET', "/vouchers/{$voucherCode}/validate", [
'headers' => ['X-plenigo-token' => eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9],
])->getBody()->getContents());
// $response contains the offer details and status of the code
// e.g. $response->status: VALID, ALREADY_REDEEMED, EXPIRED, ...
Redeem into a free offer (direct)
If the linked Frisbii Media offer has a price of zero, you can redeem the voucher directly via POST /checkout/buyWithVoucher — no checkout UI needed.
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
// @see https://api.frisbii-media-stage.com/#operation/voucherPurchase
$payload = [
'customerId' => '123',
'customerIpAddress' => $ip,
'voucherCode' => '1234-5678-1234',
];
$response = json_decode($client->request('POST', '/checkout/buyWithVoucher', [
'headers' => ['X-plenigo-token' => eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9],
'json' => $payload,
])->getBody()->getContents());
Redeem via checkout (paid or unknown offers)
If the offer is not free — or if you are unsure — pass the voucher code to preparePurchase and run the normal checkout flow. The checkout will handle a free offer correctly too, so this approach is always safe if you are uncertain.
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
// @see https://api.frisbii-media-stage.com/#operation/preparePurchase
$payload = [
'debugMode' => true,
'customerIpAddress' => $ip,
'customerId' => $customer->customerId,
'voucherCode' => '1234-5678-1234',
// no 'items' needed — the voucher code determines the offer
];
$response = json_decode($client->request('POST', '/checkout/preparePurchase', [
'headers' => ['X-plenigo-token' => eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9],
'json' => $payload,
])->getBody()->getContents());
$purchaseId = $response->purchaseId;
Then start the checkout iframe with the purchaseId as usual. See Checkout (JavaScript SDK).
Choosing the right redemption path
Situation | Use |
|---|---|
You know the offer is free | Direct: |
Offer is paid, or you are unsure | Checkout: |
You want to show the customer what they receive before redeeming | Validate first, then choose a redemption path |