<?php
declare(strict_types=1);
$merchantId = getenv('COINSSEND_MERCHANT_ID');$apiKey = getenv('COINSSEND_API_KEY');
$payload = [ 'order_id' => 'order_'.time(), 'amount' => '100.50', 'is_customer_fee' => false, 'is_customer_network_fee' => false, 'allow_card_payments' => true, 'success_url' => 'https://merchant.example/payment-success', 'cancel_url' => 'https://merchant.example/payment-cancelled',];
// PHP default json_encode flags are the API's canonical request-body format.$body = json_encode($payload, JSON_THROW_ON_ERROR);$sign = md5(base64_encode($body).$apiKey);
$handle = curl_init('https://api.coinssend.com/v1/invoices');curl_setopt_array($handle, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $body, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Merchant: '.$merchantId, 'Sign: '.$sign, ],]);
$rawResponse = curl_exec($handle);if ($rawResponse === false) { throw new RuntimeException(curl_error($handle));}
$httpStatus = curl_getinfo($handle, CURLINFO_HTTP_CODE);curl_close($handle);$response = json_decode($rawResponse, true, flags: JSON_THROW_ON_ERROR);
if ($httpStatus < 200 || $httpStatus >= 300) { throw new RuntimeException($response['error'] ?? $response['message'] ?? "HTTP {$httpStatus}");}
printf("Invoice %s: %s\n", $response['data']['code'], $response['data']['url']);Keep the API key server-side. Persist the returned invoice identifiers. A
duplicate order_id returns 409 and does not replay the original response, so
do not blindly retry an unknown outcome with a new order ID.