Buy a one-time SMS credit pack without leaving the app.
const url = 'https://api.siteqwality.com/billing/sms-credits/purchase';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"pack_id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","idempotency_key":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.siteqwality.com/billing/sms-credits/purchase \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "pack_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "idempotency_key": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0" }'The in-app replacement for POST /billing/sms-credits/checkout. It creates
a PaymentIntent rather than redirecting to Stripe’s hosted page, so the
card is collected by the Payment Element on our own Billing tab and the PAN
never touches our servers.
Nothing is credited here. The response is only a client secret; the
balance moves when the payment_intent.succeeded webhook arrives, which is
what keeps a customer who closes the tab mid-payment from being charged
without credits or credited without paying.
Authorizations
Section titled “Authorizations ”Request Body required
Section titled “Request Body required ”object
Client-generated, stable across retries of ONE confirm attempt. Same
contract as POST /billing/addons: the same value twice is one charge.
Example generated
{ "pack_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "idempotency_key": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"}Responses
Section titled “ Responses ”PaymentIntent client secret
object
Hand this to Stripe’s Payment Element to collect and confirm the card.
The credits land when payment_intent.succeeded arrives, never here.
Example generated
{ "client_secret": "example"}Unknown or inactive pack, or the card was declined
Missing or invalid authentication
Caller is not a super admin, or the account has no paid plan
Account has no Stripe customer
Internal server error