# Wallets and Topups Credyt's unique architecture unifies multiple billing models under a core primitive, the customer wallet. Every customer has one wallet, and that wallet can hold multiple accounts, each dedicated to a specific asset. Accounts are created automatically when a customer is subscribed to a product and can represent both fiat currencies or any [custom assets](https://docs.credyt.ai/features/assets.md) you define. Keeping wallets funded is critical for continuous product use. Credyt gives you two complementary ways to accept top-up payments, powered by Stripe. Hybrid Billing If you have a hybrid billing setup that leverages an external provider, be sure to read our [Adjustments](https://docs.credyt.ai/advanced-topics/adjustments-charges-gifts.md) guide. ## Option 1: Customer Billing Portal[​](#option-1-customer-billing-portal "Direct link to Option 1: Customer Billing Portal") The easiest way for your customers to add funds is through the hosted [Billing Portal](https://docs.credyt.ai/features/billing-portal.md), a self-service billing centre where they can check their balances, manage auto top-ups (recharge), and monitor their product usage: * Customers initiate top-ups directly in the portal * The only integration step is generating a session link and redirecting the customer * No sign-up is required on the customer side * The customer is responsible for defining the top-up amount * For custom assets, the default exchange rate is used Read more about the billing portal [here](https://docs.credyt.ai/features/billing-portal.md). ### Create a Billing Portal Session[​](#create-a-billing-portal-session "Direct link to Create a Billing Portal Session") [API Reference](https://docs.credyt.ai/api/billing-portal-create-portal-session.md) * REST API * TypeScript SDK * Python SDK POST https\://api.credyt.ai/billing-portal/sessions ```json { "customer_id": "{{customerId}}", "return_url": "https://glitch.ai/account", "failure_url": "https://glitch.ai/callbacks/credyt/failure" } ``` ```typescript await client.billingPortal.createPortalSession({ customerId: "{{customerId}}", returnUrl: "https://glitch.ai/account", failureUrl: "https://glitch.ai/callbacks/credyt/failure", }); ``` [View full sample on GitHub](https://github.com/credyt/sdk-ts/blob/main/samples/billingPortalCreatePortalSessionSample.ts#L11) ```python response = client.billing_portal.create_portal_session( body={ "customer_id": "{{customerId}}", "return_url": "https://glitch.ai/account", "failure_url": "https://glitch.ai/callbacks/credyt/failure", }, ) ``` [View full sample on GitHub](https://github.com/credyt/sdk-python/blob/main/samples/billing_portal_create_portal_session_start_a_session.py#L20) Redirect the customer to the `redirect_url`, where the customer can view their balance and initiate a top-up. ## Option 2: Top-up API[​](#option-2-top-up-api "Direct link to Option 2: Top-up API") Use the Top-up API when you want more control over the top-up flow, for example, if you choose to embed a top-up CTA directly within your product. * You collect or define the amount to top up in your own product * Your backend calls the Top-up API to create a checkout session * Credyt returns a `redirect_url` that navigates directly to the top-up payment page * After payment, the customer is returned to the customer billing portal * When topping up custom assets you have the option to override the default exchange rate * Use this to implement tiering or incentives ### Initiate a top-up[​](#initiate-a-top-up "Direct link to Initiate a top-up") [API Reference](https://docs.credyt.ai/api/top-ups-initiate.md) * REST API * TypeScript SDK * Python SDK POST https\://api.credyt.ai/top-ups ```json { "customer_id": "cust_473cr1y0ghbyc3m1yfbwvn3nxx", "amount": 25, "currency": "USD", "description": "Video Promotion Credits", "return_url": "https://glitch.ai/account", "failure_url": "https://glitch.ai/callbacks/credyt-failure" } ``` **Response** ```json { "id": "top_473cr1y0ghbyc3m1yfbwvn3nxx", "status": "initiated", "redirect_url": "https://billing.credyt.ai/api/sign-in?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9", "created_at": "2024-07-29T15:51:28.071Z", "expires_at": "2024-07-29T15:51:28.071Z" } ``` ```typescript await client.topUps.initiate({ customerId: "cust_473cr1y0ghbyc3m1yfbwvn3nxx", amount: 25, currency: "USD", description: "Video Promotion Credits", returnUrl: "https://glitch.ai/account", failureUrl: "https://glitch.ai/callbacks/credyt-failure", }); ``` [View full sample on GitHub](https://github.com/credyt/sdk-ts/blob/main/samples/topUpsInitiateSample.ts#L33) **SDK response object** ```typescript const response = { id: "top_473cr1y0ghbyc3m1yfbwvn3nxx", status: "initiated", redirectUrl: "https://billing.credyt.ai/api/sign-in?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9", createdAt: "2024-07-29T15:51:28.071Z", expiresAt: "2024-07-29T15:51:28.071Z", }; ``` ```python response = client.top_ups.initiate( body={ "customer_id": "cust_473cr1y0ghbyc3m1yfbwvn3nxx", "amount": 25, "currency": "USD", "description": "Video Promotion Credits", "return_url": "https://glitch.ai/account", "failure_url": "https://glitch.ai/callbacks/credyt-failure", }, ) ``` [View full sample on GitHub](https://github.com/credyt/sdk-python/blob/main/samples/top_ups_initiate_initiate_a_topup.py#L20) **SDK response object** ```python response = { "id": "top_473cr1y0ghbyc3m1yfbwvn3nxx", "status": "initiated", "redirect_url": "https://billing.credyt.ai/api/sign-in?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9", "created_at": "2024-07-29T15:51:28.071Z", "expires_at": "2024-07-29T15:51:28.071Z", } ``` Redirects the customer to the `redirect_url` to complete the top-up payment. ## Check the Wallet Balance[​](#check-the-wallet-balance "Direct link to Check the Wallet Balance") [API Reference](https://docs.credyt.ai/api/customer-wallet-ops-get-customer-wallet.md) After we receive confirmation that payment has succeeded the customer's wallet account balance will be updated. Typically this happens before the customer is redirected back to the billing portal. You can query a customer's wallet balances at any time, via the Customer Wallet API. * REST API * TypeScript SDK * Python SDK GET https\://api.credyt.ai/customers/cust\_473cr1y0ghbyc3m1yfbwvn3nxx/wallet ```http ``` **Response** ```json { "accounts": [ { "id": "default:USD", "name": "default", "asset": "USD", "available": 14.566678 }, { "id": "default:TOK", "name": "default", "asset": "TOK", "available": 993450234 } ] } ``` ```typescript await client.customerWalletOps.getCustomerWallet("cust_473cr1y0ghbyc3m1yfbwvn3nxx"); ``` [View full sample on GitHub](https://github.com/credyt/sdk-ts/blob/main/samples/walletsCustomerWalletOpsGetCustomerWalletSample.ts#L24) **SDK response object** ```typescript const response = { accounts: [ { id: "default:USD", name: "default", asset: "USD", available: 14.566678, }, { id: "default:TOK", name: "default", asset: "TOK", available: 993450234, }, ], }; ``` ```python response = client.customer_wallet_ops.get_customer_wallet( customer_id="cust_473cr1y0ghbyc3m1yfbwvn3nxx", ) ``` **SDK response object** ```python response = { "accounts": [ { "id": "default:USD", "name": "default", "asset": "USD", "available": 14.566678, }, { "id": "default:TOK", "name": "default", "asset": "TOK", "available": 993450234, }, ], } ``` ## Testing[​](#testing "Direct link to Testing") To make testing easier, all payments in test mode are processed through Credyt's default test Stripe account. We'll be adding the ability to use your own Stripe account for testing in the near future. When testing payments interactively with Stripe, you can use their standard test cards, for example: * Number: `4242 4242 4242 4242` * Expiry: Any future month/year (e.g. `12/34`) * CVC: any three‑digit CVC e.g. `123` * Any values for the other fields For the full list of test card numbers and scenarios, see [Stripe’s docs](https://docs.stripe.com/testing#cards).