chipi-stack Python package exposes the read side of Bills (get_sku_list, get_sku, get_sku_purchase). The purchase itself is a plain HTTP POST against /v1/sku-purchases — the SDK’s purchase_sku method wraps an on-chain wallet path that’s reserved for Chipi’s internal PWA, not what you want for API-key integrations.
Every endpoint on this page is guarded by Chipi’s
BearerTokenGuard and requires both an x-api-key header and a customer JWT in the Authorization: Bearer header. The JWT is issued by your auth provider; Chipi validates it against the JWKS URL you register for this API key. The Chipi API secret key (sk_dev_... / sk_prod_...) is not a valid Bearer token — passing it where a customer JWT is expected will 401.Install
Initialise the SDK
Obtain a customer JWT
Every call needs a customer JWT for theAuthorization: Bearer header. In a typical server-side flow you’d have one for the user making the purchase — from your auth provider’s session, an exchange of an API token, etc.
Browse the catalog — get_sku_list
get_sku_list accepts the same filters as the Node SDK: category (SkuCategory enum), chipi_category (curated taxonomy: "RECARGAS", "GIFT_CARDS", "GENERAL", "TELEFONIA"), carrier_name (case-insensitive substring), provider ("TET" | "CHIPI").
aget_sku_list. Same applies to all paired methods on this page.
Submit a purchase — direct POST /v1/sku-purchases
The SDK’s purchase_sku requires an on-chain wallet path that’s reserved for Chipi’s internal PWA. For API-key integrations, post to the REST endpoint directly. Body matches the CreateSkuPurchaseInput DTO:
httpx.post for httpx.AsyncClient().post — same body and headers.
Poll for settlement — get_sku_purchase
/configure/notifications in the dashboard.
DEV sandbox
WhenCHIPI_PUBLIC_KEY is a DEV key (pk_dev_...), every purchase is sandboxed:
- No real credits debited. Your
OrgBalance.availableUsdis never touched. - No carrier call. TET is never invoked.
- Deterministic SUCCESS. Every purchase succeeds within milliseconds.
pk_dev_... without worrying about credits or accidentally recharging a real phone. Swap the API key to pk_prod_... (and point catalog lookups at the production data) and the same code runs against the real carrier with no other changes.
Putting it together
✅ Verified against the live API on 2026-05-19 — exact pattern used in the production smoke purchase for sku-VIR020 (Virgin $20 MXN), settled SUCCESS in < 5s.
What’s next
- Browse the catalog visually in the dashboard at
/admin/bills. - Configure your per-transaction markup at
/configure/skus. - Set up a webhook at
/configure/notificationsso you don’t have to poll. - Need server-side billing in TypeScript? See the Node guide. React-side rendering? See the React guide.
