# Download ZBD App Source: https://docs.zbdpay.com/earn/app Get ZBD App for all your favorite platforms. ## ZBD App The ZBD App is your key to becoming a true Internet Citizen. It is available for [iOS](https://apps.apple.com/us/app/zbd-earn-bitcoin-rewards/id1484394401?mt=8) and [Android](https://play.google.com/store/apps/details?id=io.zebedee.wallet\&hl=en_US\&pli=1) mobile devices. Get ZBD Now! Get ZBD Now! ## ZBD Bots ZBD is available for your favorite chat apps Discord and Telegram. Add ZBD to your groups and servers and start zapping your friends as easily as sending a text. Get ZBD Bots for Discord Now! Get ZBD Bots for Telegram Now! # URI Schemes Source: https://docs.zbdpay.com/earn/app/uri-schemes Learn about the URI schemes ZBD App subscribes to. ## Introduction When building experiences with the ZBD API, developers may wish to open the ZBD App from their own applications to trigger users for payments, posts, requests, and more. This can be done by using specific URI schemes. ## Available Schemes To open or trigger the ZBD App on iOS or Android devices, the following URI schemes should work: ``` # Payments lnurl lightning # ZBD App zbd zeb zebedee zebedeeapp zebedeewallet ``` ## Using URI Schemes To use the URI schemes above you may craft a URL similar to the ones below: ### Open ZBD to pay a Charge ``` lightning:lnbc109......71fe ``` ### Open ZBD to pay a Static Charge ``` lnurl:lnurl1dp68gurn...e3c3svx0h ``` ### Open ZBD to automatically redeem a Voucher ``` zebedee:voucher:XXXXXXXX ``` # Global Support Source: https://docs.zbdpay.com/earn/coverage List of regions where ZBD App & Earn SDK is supported. **This page lists region coverage for ZBD Earn products (API, SDK and App)**. For ZBD Payments product region coverage, please visit [Payments Coverage](/payments/coverage). ## US States The ZBD App & Earn SDK are available in all US states, **except New York (NY)**. ## Countries The ZBD App & Earn SDK **ARE** available in the following countries: * Argentina * Australia * Austria * Belgium * Brazil * Bulgaria * Canada * Chile * Croatia * Cyprus * Czech Republic * Denmark * Estonia * Finland * France * Germany * Greece * Hungary * Iceland * Ireland * Israel * Italy * Japan * Korea, Republic of * Latvia * Lithuania * Luxembourg * Malta * Netherlands * New Zealand * Norway * Poland * Portugal * Qatar * Romania * Singapore * Slovakia * Slovenia * South Africa * Spain * Sweden * Switzerland * Taiwan * Turkey * United Arab Emirates * United Kingdom * United States ## Cashout Options Users in supported regions can withdraw their earned rewards through the following cashout methods. All cashout options are only available in the [supported regions listed above](#countries), excluding countries listed on the [Payments unsupported regions](/payments/coverage) page due to sanctions or high regulatory risk. } href="https://zbdpay.com/"> Available in all supported Earn regions **except** the following countries where the ZBD App is not available on Google Play (Android only): Canada, Israel, South Africa, Switzerland, and the United Arab Emirates. } href="https://www.speed.app/"> Available in **all** supported Earn regions. } href="https://cash.app/"> Available in the **United States** only. Available in all supported Earn regions **except** EU countries (coming soon). * Austria * Belgium * Bulgaria * Croatia * Cyprus * Czech Republic * Denmark * Estonia * Finland * France * Germany * Greece * Hungary * Ireland * Italy * Latvia * Lithuania * Luxembourg * Malta * Netherlands * Poland * Portugal * Romania * Slovakia * Slovenia * Spain * Sweden # Knowledge Base Source: https://docs.zbdpay.com/earn/knowledge-base Learn best practices for implementing secure, scalable Bitcoin rewards in your games and apps Your complete resource for mastering Bitcoin rewards integration. From security fundamentals to advanced implementation strategies, we've compiled everything you need to build successful rewarded experiences. **Built from Experience** - These guides come from real-world implementations across hundreds of games processing millions of rewards. Learn from what works. ## What You'll Find Here Protect your rewards from cheaters and hackers Proven patterns from successful integrations Step-by-step integration for Unity, Unreal, and more ## Featured Courses ### 🎮 Rewarded Play Guide Learn how to implement Bitcoin rewards that drive engagement without breaking your game economy. **Essential for Game Developers** - Understand reward economics, player psychology, and implementation strategies that have driven 40% retention increases. **What's Covered:** * Designing sustainable reward economies * Balancing fun gameplay with real rewards * Anti-cheat strategies specific to rewarded games * Case studies from successful implementations ### 🔒 Game Security Course **Required Reading** - When real money is involved, security isn't optional. This comprehensive course covers every attack vector and how to defend against it. Our 9-part security course takes you through: Start with a vulnerable example game Learn how hackers exploit games: * Hacking saved game files * Memory manipulation * Source code decompilation * Network traffic interception Implement professional security: * Server-side validation * Anti-tampering measures * Replay attack prevention * Device verification **9 Comprehensive Modules** - From basic vulnerabilities to advanced protection strategies. With code examples and real attack scenarios. ### 🛠️ Integration Guides Platform-specific guides for seamless implementation: **Most Popular** - Complete Unity integration with our drag-and-drop SDK * C# code examples * Prefab components * iOS/Android build guides * Performance optimization **Backend Integration** - Server-side rewards with Beamable * Microservice setup * Player economy design * Secure API patterns * Scaling strategies ## Why This Knowledge Matters ### The Cost of Getting It Wrong **Without Proper Security:** * Hackers drain reward pools * Fake rewards flood the system * Player trust destroyed * Potential legal issues **One game lost \$50,000 in 24 hours** due to a simple client-trust vulnerability. **Common Mistakes Cost:** * Players exploit imbalanced rewards * Server costs spiral out of control * Retention actually decreases * Negative reviews pile up **Proper implementation drives 3-5x ROI** on reward spend. **Growing Pains:** * Rewards system can't handle success * Database locks under load * API rate limits hit * Players face delays **Plan for 100x growth** from day one. ## Learning Paths Choose your journey based on your role: ### For Game Developers Start with security fundamentals (2-3 hours) Learn reward design principles (1 hour) Implement in your engine (2-4 hours) Monitor, adjust, optimize ### For Backend Engineers Focus on modules 5-9 for server security Study rate limiting and validation If using microservices architecture ### For Product Managers Understand the economics Know the risks and mitigations Learn from successful implementations ## Quick Reference ### Security Checklist * [ ] Never trust the client * [ ] Validate all rewards server-side * [ ] Implement rate limiting * [ ] Use cryptographic signatures * [ ] Monitor for anomalies * [ ] Regular security audits * [ ] Incident response plan ### Common Vulnerabilities | Attack Type | Risk Level | Prevention | | -------------------- | ---------- | ------------------------- | | Memory hacking | 🔴 High | Server validation | | Replay attacks | 🔴 High | Nonce/timestamp checks | | Save file tampering | 🟡 Medium | Encryption + server sync | | Network interception | 🟡 Medium | TLS + certificate pinning | | Fake devices | 🟡 Medium | Device attestation | ## Community Wisdom **THNDR Games**: "The security course saved us from a major vulnerability before launch" **Bitcoin Miner**: "Rewarded play guide helped us balance rewards perfectly" **Common Insight**: "We wish we'd read the security course before writing any code" **Best Practice**: "Server-side validation isn't optional - it's essential" ## Stay Updated The landscape of rewarded gaming evolves rapidly: * **New Attack Vectors** - We update the security course as new threats emerge * **Platform Changes** - Integration guides updated for latest SDKs * **Best Practices** - Community-driven improvements **Continuous Learning** - Bookmark this knowledge base and check back regularly. We add new content based on developer feedback and emerging trends. ## Get Started Don't wait until after launch to think about security and best practices: Essential for every developer Design sustainable economies Most popular platform guide *** **Talk to Our Team** - Get personalized advice for your specific implementation challenges. # Introduction Source: https://docs.zbdpay.com/earn/knowledge-base/game-security ZBD's Head of R&D and Game Security Christian Moss introduces us to the series. ``` ## Framework Integrations This is the core package. For framework-specific integrations, see: React components and hooks React Native components Flutter plugin ## Try It Out ### Interactive Example To try the interactive example locally: 1. Clone the repository: ```bash theme={null} git clone https://github.com/zbdpay/ramp-ts.git cd ramp-ts ``` 2. Start a local server: ```bash theme={null} npx http-server . -p 8000 -o /example/js.html ``` 3. Fill the form with your API key and user details 4. Click "Create Session & Load Ramp" to see it in action ### CodeSandbox Example Try it online: [CodeSandbox Demo](https://codesandbox.io/s/zbd-ramp-example) ## Resources * [GitHub Repository](https://github.com/zbdpay/ramp-ts) * [NPM Package](https://www.npmjs.com/package/@zbdpay/ramp-ts) * [API Documentation](/payments/ramp/session) * [Webhook Events](/payments/ramp/webhooks) ## Support For support and questions: * GitHub Issues: [Create an issue](https://github.com/zbdpay/ramp-ts/issues) # Create Ramp Session Source: https://docs.zbdpay.com/payments/ramp/session POST https://api.zbdpay.com/api/v1/ramp-widget Initialize a new ramp widget session for a user ## API Overview ### Base URL All API requests should be made to: ``` https://api.zbdpay.com ``` ### Authentication All ZBD endpoints are protected by an API Key. To make requests against these endpoints you must pass a header property called `apikey` with your [ZBD Project API Key](/get-started/api-keys). ```json theme={null} apikey: "your-api-key-here" ``` Get your API keys by [scheduling a call](https://zbd.one/sales) with our sales team. ### SSL / HTTPS Access **ZBD only provides a secure interface over HTTPS with SSL certificate support**. Any requests that attempt to reach the ZBD API in an insecure fashion (plain-text over HTTP requests) will be rejected. ## Description This endpoint creates a session token and widget URL that can be used to embed the ZBD Ramp widget in your game or application. ## Usage The ramp widget allows your users to purchase Bitcoin using their preferred fiat currency. The session creation process involves: Create a session with user details and configuration options Receive a widget URL and session token to embed in your application ## Configuration ### Header Parameters ZBD Project API Key Content Type ### Body Parameters Email address of the user launching the Ramp URL to receive webhook notifications Existing user session token (for returning users) Currency to convert from (e.g., USD) Currency to convert to (e.g., BTC) Destination address for the funds (Lightning Address or onchain address) Your internal reference ID for this transaction Additional metadata for the transaction ```bash cURL theme={null} curl -X POST https://api.zbdpay.com/api/v1/ramp-widget \ -H "Content-Type: application/json" \ -H "apikey: YOUR_API_KEY" \ -d '{ "email": "user@example.com", "webhook_url": "https://yourapp.com/webhooks/zbd" }' ``` ```javascript Node.js theme={null} const response = await fetch('https://api.zbdpay.com/api/v1/ramp-widget', { method: 'POST', headers: { 'Content-Type': 'application/json', 'apikey': process.env.ZBD_API_KEY }, body: JSON.stringify({ email: 'user@example.com', webhook_url: 'https://yourapp.com/webhooks/zbd' }) }); const data = await response.json(); ``` ```json Response theme={null} { "success": true, "data": { "session_token": "eyJraWQiOiJzLWE1OWNkMjc4...", "widget_url": "https://ramp.zbdpay.com/?session=eyJraWQiOiJzLWE1OWNkMjc4...", "session_id": "ses_9n3f7h2u4b", "expires_at": "2025-06-09T12:00:00Z" } } ``` ### Error Responses ```json theme={null} { "success": false, "error": { "code": "INVALID_EMAIL", "message": "Please provide a valid email address" } } ``` Common error codes: * `INVALID_EMAIL` - Email format is invalid * `INVALID_WEBHOOK_URL` - Webhook URL is not accessible * `UNAUTHORIZED` - Invalid API key * `RATE_LIMITED` - Too many requests ## Webhook Events Webhooks are sent as POST requests to your specified `webhook_url`. ### Event Structure All webhook events follow this structure: ```json theme={null} { "id": "evt_2n4f8gu3nf", "type": "ramp.purchase.completed", "created_at": "2025-06-09T10:30:00Z", "livemode": true, "data": { // Event-specific data } } ``` # Themes Customization Source: https://docs.zbdpay.com/payments/ramp/themes Customize every visual element of ZBD Ramp to match your brand ZBD Ramp provides complete control over the widget's appearance through an advanced theming system. Customize every visual element to create a seamless brand experience. ## Theme Options ### Pre-built Themes Start with our professionally designed themes: Clean, bright interface perfect for daytime use and professional applications Modern dark interface that reduces eye strain and saves battery on OLED screens ## Live Preview Editor ZBD Ramp Live Preview Editor The ZBD Developer Dashboard features a powerful Live Preview editor that makes customization intuitive and immediate. ### How It Works Navigate to Ramp → Theme in your ZBD Developer Dashboard Click directly on any element in the preview to select it Adjust the element's properties in the side panel Watch your changes apply in real-time Save your custom theme when satisfied ### Customizable Properties For every element in the widget, you can customize: * **Background Color**: Primary background color * **Text Color**: Primary text color * **Border Color**: Element border color * **Border Radius**: Corner rounding * **Hover Background**: Background color on hover * **Hover Text**: Text color on hover * **Active Background**: Background when clicked/active * **Active Text**: Text color when active * **Disabled State**: Appearance when disabled * **Shadow**: Box shadow effects * **Padding & Margins**: Spacing adjustments ## Custom Theme JSON Every theme configuration is exportable as JSON, allowing you to: * Version control your theme * Share themes across projects * Backup theme configurations * Programmatically apply themes ### Example Theme JSON ```json theme={null} { "name": "My Custom Theme", "base": "light", "variables": { "--primary": "210 100% 50%", "--primary-foreground": "0 0% 100%", "--secondary": "210 40% 96%", "--secondary-foreground": "222 47% 11%", "--accent": "210 40% 90%", "--accent-foreground": "222 47% 11%", "--destructive": "0 84% 60%", "--destructive-foreground": "0 0% 100%", "--border": "214 32% 91%", "--input": "214 32% 91%", "--ring": "210 100% 50%", "--radius": "0.5rem", "--widget-background": "#FFFFFF", "--widget-card-background": "#FAFAFA", "--amount-input-display-text": "#000000", "--amount-input-display-error": "#ef4444", "--amount-input-quick-amount-bg": "#F5F5F5", "--amount-input-quick-amount-text": "#000000", "--amount-input-quick-amount-border": "#E0E0E0", "--amount-input-quick-amount-hover-bg": "#EEEEEE", "--amount-input-quick-amount-active-bg": "#E0E0E0", "--amount-input-numpad-bg": "transparent", "--amount-input-numpad-text": "#000000", "--amount-input-numpad-hover-bg": "#F5F5F5", "--amount-input-numpad-active-bg": "#EEEEEE", "--button-primary-bg": "210 100% 50%", "--button-primary-text": "0 0% 100%", "--button-primary-hover-bg": "210 100% 45%", "--button-primary-active-bg": "210 100% 40%", "--button-secondary-bg": "210 40% 96%", "--button-secondary-text": "222 47% 11%", "--button-secondary-hover-bg": "210 40% 92%", "--button-secondary-active-bg": "210 40% 88%" } } ``` ### Importing/Exporting Themes #### Export Your Theme 1. Open the Theme editor in your dashboard 2. Click "Export Theme" button 3. Copy the JSON or download as a file #### Import a Theme 1. Open the Theme editor 2. Click "Import Theme" 3. Paste your JSON or upload a file 4. Preview and apply ## Version Control Integration ### Best Practices 1. **Store in Repository**: Keep your theme JSON in your project repository 2. **Use Environment Configs**: Different themes for dev/staging/production 3. **Document Changes**: Comment significant theme updates 4. **Test Across Devices**: Ensure theme works on all screen sizes ## Testing Your Theme Always test your custom theme across different devices and browsers to ensure a consistent experience. ## Support Need help with theme customization? * Use the Live Preview in your [ZBD Developer Dashboard](https://dashboard.zbdpay.com) * Contact your ZBD account manager for advanced customization * Review our example themes in the dashboard # User Flow Walkthrough Source: https://docs.zbdpay.com/payments/ramp/user-flow Visual walkthrough of the complete ZBD Ramp user experience This guide walks through the complete user journey in the ZBD Ramp widget, from initial screen to completed purchase. Use this reference to understand what your users will experience when buying Bitcoin through your app. ## 1. Initial Screen When users first launch the ramp widget, they're greeted with a clean, intuitive interface to begin their purchase journey. ZBD Ramp Initial Screen The initial screen presents the core functionality and guides users to begin the purchase process. *** ## 2. Email Verification To ensure account security and compliance, users must verify their email address before proceeding. Email Verification Screen Users receive a verification code via email and enter it to confirm their identity and proceed to KYC. *** ## 3. KYC Flow The Know Your Customer (KYC) process is streamlined into clear steps. This is required for regulatory compliance and fraud prevention. ### Step 1: Getting Started KYC Initial Screen Users are introduced to the KYC process and what information they'll need to provide. ### Step 2: Country Selection Country Selection Users select their country of residence. This determines available payment methods and compliance requirements. ### Step 3: Personal Information Personal Information Form Users provide basic personal information including full name, date of birth, and other required details. ### Step 4: Address Address Form Users enter their residential address for identity verification purposes. ### Step 5: Document Selection Document Type Selection Users choose which type of government-issued ID they'll upload (passport, driver's license, etc.). ### Step 6: Document Upload Document Upload Screen Users can upload documents directly or receive a secure link to complete the upload on their phone. Upload from Phone Users can scan a QR code or receive a link to upload from their mobile device. Secure Link Option A secure, one-time link is generated for mobile document uploads. Phone Connected Confirmation that the mobile device is connected and ready for upload. *** ## 4. KYC Processing After submitting KYC information, users enter the verification stage. KYC Processing Users see a processing screen while their information is being verified. This typically takes just a few moments. KYC Success Upon successful verification, users are cleared to proceed with their purchase. KYC Failed If verification fails, users receive clear guidance on next steps or alternative options. *** ## 5. Payment Method Selection Once KYC is approved, users choose how they want to pay for their Bitcoin. Payment Method Selection Users can connect their bank account via Plaid for ACH payments. Additional payment methods are coming soon. If a user hasn't linked a bank account yet, they'll see an option to connect via Plaid. Payment Method - No Bank Linked *** ## 6. Plaid Bank Connection To enable bank payments, users securely connect their bank account through Plaid. ### Plaid Flow Steps Plaid Initial Screen Users are introduced to the secure Plaid connection process. Bank Institution Selection Users search for and select their bank from thousands of supported institutions. Bank Authentication Users log into their bank account securely through Plaid's interface. Bank Connected Successfully Confirmation that the bank account is successfully connected and ready for payments. *** ## 7. Payment Confirmation After payment method setup, users confirm their purchase details. Payment Confirmation Success Users see a success screen confirming their Bitcoin purchase and delivery details. Payment Confirmation Failed If the payment fails, users receive clear error messages and options to retry. *** ## 8. Transaction Management Users can view their transaction history and details at any time. ### Transaction History Transaction History A comprehensive list of all past and pending transactions, with status indicators for easy tracking. ### Transaction Details Transaction Details Detailed view of individual transactions including amounts, timestamps, fees, and destination addresses. *** ## Integration Tips Design your app to seamlessly transition users into the ramp widget. Consider the context and timing of when you present the purchase option. Implement webhook handlers to process purchase events and update your app state in real-time as users progress through the flow. *** ## Next Steps Learn how to integrate the ZBD Ramp widget into your application Customize the widget's theme to match your brand Handle webhook events to track user progress and purchases Explore the complete API documentation # Webhook Events Source: https://docs.zbdpay.com/payments/ramp/webhooks Complete reference for ZBD Ramp webhook events ## Overview Webhooks allow you to receive real-time notifications about events that occur during the ZBD Ramp lifecycle. From session initialization to payment completion, webhooks provide crucial updates about your users' transactions. ZBD Ramp sends webhook events to your specified endpoint as HTTP POST requests. Each event contains detailed information about what occurred, allowing you to update your systems accordingly. ### Webhook URL Setup Configure your webhook URL when creating a session: ```typescript @zbdpay/ramp-ts theme={null} import { initRampSession, QuoteCurrencyEnum, BaseCurrencyEnum } from '@zbdpay/ramp-ts'; const response = await initRampSession({ apikey: process.env.ZBD_API_KEY, email: 'user@example.com', destination: 'lightning-address@zbd.gg', quote_currency: QuoteCurrencyEnum.USD, base_currency: BaseCurrencyEnum.BTC, webhook_url: 'https://app.xyz/webhooks/zbd', // <---- YOUR WEBHOOK URL HERE reference_id: 'order-123', metadata: { userId: 'user-456', plan: 'premium' } }); const sessionToken = response.data.session_token; ``` ```typescript Fetch theme={null} const response = await fetch('https://api.zbdpay.com/api/v1/ramp-widget', { method: 'POST', headers: { 'Content-Type': 'application/json', 'apikey': process.env.ZBD_API_KEY }, body: JSON.stringify({ email: 'user@example.com', destination: 'lightning-address@zbd.gg', quote_currency: 'USD', base_currency: 'BTC', webhook_url: 'https://app.xyz/webhooks/zbd', // <---- YOUR WEBHOOK URL HERE reference_id: 'order-123', metadata: { userId: 'user-456', plan: 'premium' } }) }); const data = await response.json(); const sessionToken = data.data.session_token; ``` ## Event Categories Webhook events are organized into six main categories: Widget lifecycle events User verification events Identity verification events Bank connection events Transaction events Crypto delivery events ## Event Structure All webhook events follow a consistent structure: ```json theme={null} { "event": "RAMP_WIDGET.V1.EVENT_NAME", "data": { "email": "user@example.com", "session_id": "sess_abc123xyz789", // Event-specific data "metadata": { // Your custom metadata } }, "url": "https://partner.com/webhooks", "created_at": "2025-01-18T10:30:00Z" } ``` ## Complete Event Reference ### Session Events **Event:** `RAMP_WIDGET.V1.SESSION.INITIATED` Triggered when a Ramp session is successfully initiated. ```json theme={null} { "event": "RAMP_WIDGET.V1.SESSION.INITIATED", "data": { "email": "user@example.com", "session_id": "sess_abc123xyz789" }, "url": "https://partner.com/webhooks", "created_at": "2025-01-18T10:30:00Z" } ``` **Event:** `RAMP_WIDGET.V1.SESSION.CLOSED` Fired when a Ramp session is closed, either by unmount, user action, or completion. ```json theme={null} { "event": "RAMP_WIDGET.V1.SESSION.CLOSED", "data": { "email": "user@example.com", "session_id": "sess_abc123xyz789" }, "url": "https://partner.com/webhooks", "created_at": "2025-01-18T11:15:00Z" } ``` ### Authentication Events **Event:** `RAMP_WIDGET.V1.CODE_VERIFICATION.SUCCEEDED` Sent when a user successfully verifies their 6-digit code. ```json theme={null} { "event": "RAMP_WIDGET.V1.CODE_VERIFICATION.SUCCEEDED", "data": { "email": "user@example.com", "session_id": "sess_abc123xyz789" }, "url": "https://partner.com/webhooks", "created_at": "2025-01-18T10:32:00Z" } ``` **Event:** `RAMP_WIDGET.V1.CODE_VERIFICATION.FAILED` Triggered when a 6-digit code verification attempt fails. ```json theme={null} { "event": "RAMP_WIDGET.V1.CODE_VERIFICATION.FAILED", "data": { "email": "user@example.com", "session_id": "sess_abc123xyz789" }, "url": "https://partner.com/webhooks", "created_at": "2025-01-18T10:33:00Z" } ``` **Event:** `RAMP_WIDGET.V1.USER_ACCESS_TOKEN.CREATED` Fired when user access and refresh tokens are generated. ```json theme={null} { "event": "RAMP_WIDGET.V1.USER_ACCESS_TOKEN.CREATED", "data": { "email": "user@example.com", "session_id": "sess_abc123xyz789", "access_token_id": "tok_abc123", "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "access_token_expires_at": "2025-01-18T11:45:00Z", "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refresh_token_expires_at": "2025-02-18T10:45:00Z", "metadata": { "customer_id": "cust_123", "source": "widget" } }, "url": "https://partner.com/webhooks", "created_at": "2025-01-18T10:45:00Z" } ``` ### KYC Events **Event:** `RAMP_WIDGET.V1.KYC.INITIATED` Fired when KYC (Know Your Customer) verification process is initiated. ```json theme={null} { "event": "RAMP_WIDGET.V1.KYC.INITIATED", "data": { "email": "user@example.com", "session_id": "sess_abc123xyz789", "metadata": { "customer_id": "cust_123", "source": "widget" } }, "url": "https://partner.com/webhooks", "created_at": "2025-01-18T10:35:00Z" } ``` **Event:** `RAMP_WIDGET.V1.KYC.PROCESSING` Indicates that KYC verification is being processed. ```json theme={null} { "event": "RAMP_WIDGET.V1.KYC.PROCESSING", "data": { "email": "user@example.com", "session_id": "sess_abc123xyz789", "metadata": { "customer_id": "cust_123", "source": "widget" } }, "url": "https://partner.com/webhooks", "created_at": "2025-01-18T10:36:00Z" } ``` **Event:** `RAMP_WIDGET.V1.KYC.COMPLETED` Sent when KYC verification is successfully completed. ```json theme={null} { "event": "RAMP_WIDGET.V1.KYC.COMPLETED", "data": { "email": "user@example.com", "session_id": "sess_abc123xyz789", "metadata": { "customer_id": "cust_123", "source": "widget" } }, "url": "https://partner.com/webhooks", "created_at": "2025-01-18T10:40:00Z" } ``` **Event:** `RAMP_WIDGET.V1.KYC.REJECTED` Triggered when KYC verification is rejected or fails. ```json theme={null} { "event": "RAMP_WIDGET.V1.KYC.REJECTED", "data": { "email": "user@example.com", "session_id": "sess_abc123xyz789", "metadata": { "customer_id": "cust_123", "source": "widget" } }, "url": "https://partner.com/webhooks", "created_at": "2025-01-18T10:41:00Z" } ``` ### Bank Connection Events **Event:** `RAMP_WIDGET.V1.BANK_CONNECTION.INITIATED` Triggered when bank connection flow is initiated. ```json theme={null} { "event": "RAMP_WIDGET.V1.BANK_CONNECTION.INITIATED", "data": { "email": "user@example.com", "session_id": "sess_abc123xyz789", "metadata": { "customer_id": "cust_123", "source": "widget" } }, "url": "https://partner.com/webhooks", "created_at": "2025-01-18T10:50:00Z" } ``` **Event:** `RAMP_WIDGET.V1.BANK_CONNECTION.COMPLETED` Sent when bank connection is successfully established. ```json theme={null} { "event": "RAMP_WIDGET.V1.BANK_CONNECTION.COMPLETED", "data": { "email": "user@example.com", "session_id": "sess_abc123xyz789", "metadata": { "customer_id": "cust_123", "source": "widget" } }, "url": "https://partner.com/webhooks", "created_at": "2025-01-18T10:55:00Z" } ``` **Event:** `RAMP_WIDGET.V1.BANK_CONNECTION.FAILED` Fired when bank connection attempt fails. ```json theme={null} { "event": "RAMP_WIDGET.V1.BANK_CONNECTION.FAILED", "data": { "email": "user@example.com", "session_id": "sess_abc123xyz789", "metadata": { "customer_id": "cust_123", "source": "widget" } }, "url": "https://partner.com/webhooks", "created_at": "2025-01-18T10:56:00Z" } ``` ### Payment Events **Event:** `RAMP_WIDGET.V1.PAYMENT.INITIATED` Triggered when a payment transaction is initiated. ```json theme={null} { "event": "RAMP_WIDGET.V1.PAYMENT.INITIATED", "data": { "email": "user@example.com", "session_id": "sess_abc123xyz789", "base_amount": "100.00", "base_currency": "USD", "quote_amount": "0.0025", "quote_currency": "BTC", "metadata": { "customer_id": "cust_123", "source": "widget" } }, "url": "https://partner.com/webhooks", "created_at": "2025-01-18T11:00:00Z" } ``` **Event:** `RAMP_WIDGET.V1.PAYMENT.SETTLED` Sent when a payment transaction is successfully settled. ```json theme={null} { "event": "RAMP_WIDGET.V1.PAYMENT.SETTLED", "data": { "email": "user@example.com", "session_id": "sess_abc123xyz789", "base_amount": "100.00", "base_currency": "USD", "quote_amount": "0.0025", "quote_currency": "BTC", "metadata": { "customer_id": "cust_123", "source": "widget" } }, "url": "https://partner.com/webhooks", "created_at": "2025-01-18T11:05:00Z" } ``` **Event:** `RAMP_WIDGET.V1.PAYMENT.FAILED` Fired when a payment transaction fails. ```json theme={null} { "event": "RAMP_WIDGET.V1.PAYMENT.FAILED", "data": { "email": "user@example.com", "session_id": "sess_abc123xyz789", "base_amount": "100.00", "base_currency": "USD", "quote_amount": "0.0025", "quote_currency": "BTC", "metadata": { "customer_id": "cust_123", "source": "widget" } }, "url": "https://partner.com/webhooks", "created_at": "2025-01-18T11:06:00Z" } ``` ### Withdrawal Events **Event:** `RAMP_WIDGET.V1.WITHDRAWAL.SUCCEEDED` Triggered when a withdrawal is successfully completed. ```json theme={null} { "event": "RAMP_WIDGET.V1.WITHDRAWAL.SUCCEEDED", "data": { "email": "user@example.com", "session_id": "sess_abc123xyz789", "base_amount": "100.00", "base_currency": "USD", "quote_amount": "0.0025", "quote_currency": "BTC", "destination": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh", "payment_hash": "c0ff35a42445041592aa5ff982606971ae46b3f9df0a100cb15f05f61718f223", "metadata": { "customer_id": "cust_123", "source": "widget" } }, "url": "https://partner.com/webhooks", "created_at": "2025-01-18T11:10:00Z" } ``` **Event:** `RAMP_WIDGET.V1.WITHDRAWAL.FAILED` Sent when a withdrawal attempt fails. ```json theme={null} { "event": "RAMP_WIDGET.V1.WITHDRAWAL.FAILED", "data": { "email": "user@example.com", "session_id": "sess_abc123xyz789", "base_amount": "100.00", "base_currency": "USD", "quote_amount": "0.0025", "quote_currency": "BTC", "destination": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh", "metadata": { "customer_id": "cust_123", "source": "widget" } }, "url": "https://partner.com/webhooks", "created_at": "2025-01-18T11:11:00Z" } ``` ## Webhook Implementation ### Basic Handler Examples Here are webhook handler implementations in popular frameworks: ```typescript Next.js theme={null} // app/api/webhooks/zbd/route.ts import { NextRequest, NextResponse } from 'next/server'; export async function POST(request: NextRequest) { const event = await request.json(); // Log the event console.log(`Received webhook: ${event.event}`); // Handle different event types switch(event.event) { case 'RAMP_WIDGET.V1.PAYMENT.SETTLED': // Update user balance, send confirmation, etc. await handlePaymentSettled(event.data); break; case 'RAMP_WIDGET.V1.KYC.COMPLETED': // Update user verification status await handleKYCCompleted(event.data); break; case 'RAMP_WIDGET.V1.WITHDRAWAL.SUCCEEDED': // Log successful withdrawal await handleWithdrawalSuccess(event.data); break; default: console.log(`Unhandled event type: ${event.event}`); } // Always respond with 200 OK return NextResponse.json({ received: true }, { status: 200 }); } async function handlePaymentSettled(data: any) { // Your payment processing logic console.log('Payment settled:', data); } async function handleKYCCompleted(data: any) { // Your KYC completion logic console.log('KYC completed:', data); } async function handleWithdrawalSuccess(data: any) { // Your withdrawal success logic console.log('Withdrawal succeeded:', data); } ``` ```go Go theme={null} package main import ( "encoding/json" "fmt" "io/ioutil" "log" "net/http" ) type WebhookEvent struct { Event string `json:"event"` Data map[string]interface{} `json:"data"` URL string `json:"url"` CreatedAt string `json:"created_at"` } func webhookHandler(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } body, err := ioutil.ReadAll(r.Body) if err != nil { http.Error(w, "Error reading body", http.StatusBadRequest) return } var event WebhookEvent err = json.Unmarshal(body, &event) if err != nil { http.Error(w, "Error parsing JSON", http.StatusBadRequest) return } // Log the event log.Printf("Received webhook: %s", event.Event) // Handle different event types switch event.Event { case "RAMP_WIDGET.V1.PAYMENT.SETTLED": handlePaymentSettled(event.Data) case "RAMP_WIDGET.V1.KYC.COMPLETED": handleKYCCompleted(event.Data) case "RAMP_WIDGET.V1.WITHDRAWAL.SUCCEEDED": handleWithdrawalSuccess(event.Data) default: log.Printf("Unhandled event type: %s", event.Event) } // Always respond with 200 OK w.WriteHeader(http.StatusOK) fmt.Fprintf(w, "OK") } func handlePaymentSettled(data map[string]interface{}) { // Your payment processing logic log.Printf("Payment settled: %v", data) } func handleKYCCompleted(data map[string]interface{}) { // Your KYC completion logic log.Printf("KYC completed: %v", data) } func handleWithdrawalSuccess(data map[string]interface{}) { // Your withdrawal success logic log.Printf("Withdrawal succeeded: %v", data) } func main() { http.HandleFunc("/webhooks/zbd", webhookHandler) log.Println("Server starting on :8080") log.Fatal(http.ListenAndServe(":8080", nil)) } ``` ```rust Rust theme={null} use actix_web::{web, App, HttpResponse, HttpServer, Result}; use serde::{Deserialize, Serialize}; use serde_json::Value; #[derive(Debug, Deserialize, Serialize)] struct WebhookEvent { event: String, data: Value, url: String, created_at: String, } async fn webhook_handler(event: web::Json) -> Result { // Log the event println!("Received webhook: {}", event.event); // Handle different event types match event.event.as_str() { "RAMP_WIDGET.V1.PAYMENT.SETTLED" => { handle_payment_settled(&event.data).await; } "RAMP_WIDGET.V1.KYC.COMPLETED" => { handle_kyc_completed(&event.data).await; } "RAMP_WIDGET.V1.WITHDRAWAL.SUCCEEDED" => { handle_withdrawal_success(&event.data).await; } _ => { println!("Unhandled event type: {}", event.event); } } // Always respond with 200 OK Ok(HttpResponse::Ok().body("OK")) } async fn handle_payment_settled(data: &Value) { // Your payment processing logic println!("Payment settled: {:?}", data); } async fn handle_kyc_completed(data: &Value) { // Your KYC completion logic println!("KYC completed: {:?}", data); } async fn handle_withdrawal_success(data: &Value) { // Your withdrawal success logic println!("Withdrawal succeeded: {:?}", data); } #[actix_web::main] async fn main() -> std::io::Result<()> { println!("Server starting on http://127.0.0.1:8080"); HttpServer::new(|| { App::new() .route("/webhooks/zbd", web::post().to(webhook_handler)) }) .bind("127.0.0.1:8080")? .run() .await } ``` ```javascript Node.js/Express theme={null} app.post('/webhooks/zbd', (req, res) => { const event = req.body; // Log the event console.log(`Received webhook: ${event.event}`); // Handle different event types switch(event.event) { case 'RAMP_WIDGET.V1.PAYMENT.SETTLED': // Update user balance, send confirmation, etc. handlePaymentSettled(event.data); break; case 'RAMP_WIDGET.V1.KYC.COMPLETED': // Update user verification status handleKYCCompleted(event.data); break; case 'RAMP_WIDGET.V1.WITHDRAWAL.SUCCEEDED': // Log successful withdrawal handleWithdrawalSuccess(event.data); break; default: console.log(`Unhandled event type: ${event.event}`); } // Always respond with 200 OK res.status(200).send('OK'); }); function handlePaymentSettled(data) { // Your payment processing logic console.log('Payment settled:', data); } function handleKYCCompleted(data) { // Your KYC completion logic console.log('KYC completed:', data); } function handleWithdrawalSuccess(data) { // Your withdrawal success logic console.log('Withdrawal succeeded:', data); } ``` ```python Python/Flask theme={null} from flask import Flask, request, jsonify app = Flask(__name__) @app.route('/webhooks/zbd', methods=['POST']) def handle_webhook(): event = request.json # Log the event print(f"Received webhook: {event['event']}") # Handle different event types if event['event'] == 'RAMP_WIDGET.V1.PAYMENT.SETTLED': handle_payment_settled(event['data']) elif event['event'] == 'RAMP_WIDGET.V1.KYC.COMPLETED': handle_kyc_completed(event['data']) elif event['event'] == 'RAMP_WIDGET.V1.WITHDRAWAL.SUCCEEDED': handle_withdrawal_success(event['data']) else: print(f"Unhandled event type: {event['event']}") # Always respond with 200 OK return 'OK', 200 def handle_payment_settled(data): # Your payment processing logic print(f"Payment settled: {data}") def handle_kyc_completed(data): # Your KYC completion logic print(f"KYC completed: {data}") def handle_withdrawal_success(data): # Your withdrawal success logic print(f"Withdrawal succeeded: {data}") if __name__ == '__main__': app.run(port=8080) ``` ## Security Best Practices **Important:** Always validate webhook authenticity before processing events. ### Webhook Verification 1. **Use HTTPS Only** - Always use HTTPS endpoints for webhooks 2. **Verify Signatures** - Validate webhook signatures when provided 3. **IP Allowlisting** - Restrict webhook access to ZBD IP addresses 4. **Idempotency** - Handle duplicate events gracefully 5. **Timeout Handling** - Respond quickly (within 5 seconds) ### Error Handling * Always respond with `200 OK` status, even if processing fails * Log all webhook events for debugging * Implement retry logic for critical operations * Use message queues for asynchronous processing ## Testing Webhooks ### Local Development Use tools like [ngrok](https://ngrok.com) to expose your local webhook endpoint: ```bash theme={null} ngrok http 3000 ``` Then use the ngrok URL as your webhook endpoint during development. ### Webhook Testing Checklist Essential events to handle: * ✅ PAYMENT.SETTLED * ✅ WITHDRAWAL.SUCCEEDED * ✅ PAYMENT.FAILED * ✅ WITHDRAWAL.FAILED Improve user experience: * ✅ KYC.COMPLETED * ✅ KYC.REJECTED * ✅ BANK\_CONNECTION.COMPLETED * ✅ SESSION.CLOSED For advanced integrations: * ⚪ SESSION.INITIATED * ⚪ CODE\_VERIFICATION.SUCCEEDED * ⚪ KYC.INITIATED * ⚪ PAYMENT.INITIATED ## Troubleshooting ### Common Issues * Verify your webhook URL is publicly accessible * Check for firewall or security rules blocking requests * Ensure your endpoint responds with 200 status * Confirm webhook URL was correctly set during session creation * Implement idempotency using the session\_id * Store processed event IDs to prevent reprocessing * Use database transactions for critical operations * Process webhooks asynchronously using queues * Respond immediately with 200 OK * Move heavy processing to background jobs ## Next Steps Learn how to create widget sessions Complete integration walkthrough # ZBD Payments SDK Source: https://docs.zbdpay.com/payments/sdk Use ZBD Payments in your preferred development environment. ## Official SDKs The following SDKs are maintained by the ZBD Payments core team. Easiest way to interact with the ZBD Payments APIs. Quickstart guides and source code for Next.js, Node.js, and Express applications. Python SDK for ZBD Payments APIs. Includes support for Django, Flask and FastAPI frameworks.
## Community SDKs Supported by the ZBD open source developer community. Rust SDK for ZBD Payments APIs Go SDK for ZBD Payments APIs C# SDK for ZBD Payments APIs # C# SDK Source: https://docs.zbdpay.com/payments/sdk/csharp Learn how to send and receive instant Bitcoin payments with C# and ZBD. ## Prerequisites To complete this guide, you will need the following: * [ZBD Project with a Live API key](/get-started/api-keys) * [Visual Studio](https://visualstudio.microsoft.com/downloads/) ## 1. Create project Create a new project or open an existing project in Visual Studio. ## 2. Install the ZBD NuGet package NuGet package name: `dev.zbd.csharp` ```bash Package Manager theme={null} NuGet\Install-Package dev.zbd.csharp ``` ```bash .NET CLI theme={null} dotnet add package dev.zbd.csharp ``` ```xml Package Reference theme={null} ``` ## 3. Send and receive Bitcoin The below code is an example of how you can create a charge. ```csharp theme={null} using ZebedeeAPI; var handler = new ZebedeeHandler(""); var charge = await handler.CreateCharge( expiresIn: "10000", amount: "100000", description: "A Charge Created with ZBD!" ); Console.WriteLine(charge.data.invoice.request); ``` You're looking for the `data.invoice.request` property in the JSON response. It starts with `lnbc1` and is the payment request anyone in the Bitcoin Lightning Network can use to pay you. ``` lnbc1u1pjdlax9pp5t7jhkd7h2wntd4f2v7xp22dknmjxp0q8nm7hfcny4p7a5mr7x3rsdp9f4hkueteypshggrfde6x2unwv46zqumsv4jkgcqzzsxqzjcsp5dsayu6m6632p28rnkeeqsr7d54amrkv6wh46yrv42gdgca8xl8gs9qyyssqgj2zrkax733rzulfkzc5mqsr8fpwrva82stpa7e0frw32722trv37jlq8mvlqfp8y75lr6mz63zd7qnxar8hhsehuy22pvfq6wjxwqqqa60lx3 ``` Charges and payment requests are usually shown to users as QR codes that can be scanned by mobile apps (e.g. [ZBD](https://zbd.one/download)). Read [Callbacks](/payments/api/callbacks) to understand how to receive updates about your payment asynchronously. # Go SDK Source: https://docs.zbdpay.com/payments/sdk/go Learn how to use the Go SDK to send Bitcoin to any Email. This guide is coming soon. Until then you can check the [Go SDK repository](https://github.com/zebedeeio/go-sdk). # Python SDK Source: https://docs.zbdpay.com/payments/sdk/python Learn how to send and receive instant Bitcoin payments with Python and ZBD. ## Prerequisites To complete this guide, you will need the following: * [ZBD Project with a Live API key](/get-started/api-keys) * Python 3.8 or higher ## 1. Install the ZBD Python package Install the official ZBD Python SDK from PyPI: ```bash theme={null} pip install zbdpay ``` ## 2. Send and receive Bitcoin Get started with just a few lines of code. Here's how to send a payment to any Lightning Address: ```python theme={null} import os from zbdpay import ZbdPayments # Initialize the client client = ZbdPayments( apikey=os.environ.get("ZBD_PAYMENTS_API_KEY") ) # Send instant Bitcoin payment response = client.lightning_address.send_payment( amount="500000", # Amount in millisatoshis comment="Instant global payments", ln_address="andre@zbd.gg" ) print(f"Payment sent! Transaction ID: {response.data.id}") ``` ## 3. Create a payment request Accept Bitcoin payments by creating a charge: ```python theme={null} # Create a charge (payment request) charge = client.lightning_charges.create( amount="100000", # 100 satoshis description="Payment for your product", expires_in=300 # Expires in 5 minutes ) print(f"Payment Request: {charge.data.invoice.request}") print(f"QR Code: {charge.data.invoice.uri}") ``` You're looking for the `data.invoice.request` property in the response. It starts with `lnbc1` and is the payment request anyone in the Bitcoin Lightning Network can use to pay you. Payment requests are usually shown to users as QR codes that can be scanned by mobile apps (e.g. [ZBD](https://zbd.one/download)). Read [Callbacks](/payments/api/callbacks) to understand how to receive updates about your payments asynchronously. ## Async Support The SDK also supports async operations for better performance: ```python theme={null} import asyncio from zbdpay import AsyncZbdPayments async def main(): client = AsyncZbdPayments( apikey=os.environ.get("ZBD_PAYMENTS_API_KEY") ) # Send payment asynchronously await client.lightning_address.send_payment( amount="500000", comment="Async payment", ln_address="andre@zbd.gg" ) asyncio.run(main()) ``` ## Next Steps Ready to dive deeper? Check out these resources: Explore the source code and contribute to the SDK View the official Python package on PyPI with full documentation ## Advanced Usage For more advanced features like custom timeouts, retries, and raw response access, check out the [full documentation on PyPI](https://pypi.org/project/zbdpay). # Rust SDK Source: https://docs.zbdpay.com/payments/sdk/rust Learn how to send and receive instant Bitcoin payments with Rust and ZBD. ## Prerequisites To complete this guide, you will need the following: * [ZBD Project with a Live API key](/get-started/api-keys) * [Rust](https://www.rust-lang.org/tools/install) and [cargo](https://www.rust-lang.org/tools/install) installed ## 1. Create a Rust project ```bash theme={null} cargo new cd ``` ## 2. Install dependencies Add both the `zebedee-rust` and `tokio` crates to your project: ```bash theme={null} cargo add zebedee-rust tokio ``` ## 3. Update your Cargo.toml Update your `Cargo.toml` file to use full features in tokio. ```yaml theme={null} [package] name = "zbd-rust" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] tokio = { version = "1.29.1", features = ['full']} zebedee-rust = "0.4.4" ``` ## 4. Create a Charge Open your project's `main.rs` file and add the following code: ```rust theme={null} use std::env; use zebedee_rust::{charges::*, ZebedeeClient}; #[tokio::main] async fn main(){ let apikey: String = env::var("ZBD_API_KEY").unwrap(); let zbd_client = ZebedeeClient::new().apikey(apikey).build(); let charge = Charge{ amount: String::from("5000"), ..Default::default() }; let charges_res = zbd_client.create_charge(&charge).await.unwrap(); println!("{:?}", charge_res); } ``` Make sure to create an environment variable called **ZBD\_API\_KEY** in your Rust project. This is the API key you get from your ZBD Project. Run the following command to create your charge: ```bash theme={null} cargo run ``` You can now create charges using the ZBD and Rust! Charges and payment requests are usually shown to users as QR codes that can be scanned by mobile apps (e.g. [ZBD](https://zbd.one/download)). Read [Callbacks](/payments/api/callbacks) to understand how to receive updates about your payment asynchronously. ## 5. Try it yourself You can now begin receiving instant Bitcoin payments with Rust + ZBD! See the full source code. # TypeScript SDK Source: https://docs.zbdpay.com/payments/sdk/typescript ZBD is your one-stop shop API for all things instant payments in TypeScript. ## Installation ```bash theme={null} pnpm install @zbdpay/payments-sdk ``` ## Quickstart Use the following guides to get started with the TypeScript SDK for ZBD Payments: } href="/payments/sdk/typescript/next"> Application codebase that allows you to quickly get started with ZBD and Next.js -- ZBD API Playground and a Starter Kit for ZBD-powered Next.js apps. } href="/payments/sdk/typescript/vercel/send" /> } href="/payments/sdk/typescript/supabase/send" /> # Express Source: https://docs.zbdpay.com/payments/sdk/typescript/express Learn how to send and receive instant Bitcoin payments with Express and ZBD. ## Prerequisites To complete this guide, you will need the following: * [ZBD Project with a Live API key](/get-started/api-keys) ## 1. Create a Node.js project Start with a brand new empty directory called `express-example` and run the following command to initiate a Node.js project: ```bash theme={null} npm init -y ``` ## 2. Install Express.js Inside your project directory, run the following command to install Express.js: ```bash yarn theme={null} yarn add express ``` ```bash npm theme={null} npm install express ``` ```bash pnpm theme={null} pnpm add express ``` ## 3. Install @zbdpay/payments-sdk Node.js SDK Inside your Express.js ```bash yarn theme={null} yarn add @zbdpay/payments-sdk ``` ```bash npm theme={null} npm install @zbdpay/payments-sdk ``` ```bash pnpm theme={null} pnpm add @zbdpay/payments-sdk ``` ## 4. Send and receive Bitcoin Create a new file called `index.js` and add the following code: ```js theme={null} import express from "express"; import ZbdPayments from '@zbdpay/payments-sdk'; const ZBD_API_KEY = 'b7YW3s2JzZKGcXjIf5Dqof8wjKT2RuWr8'; // dummy key const client = new ZbdPayments({ apikey: ZBD_API_KEY, }); // Create Express app const app = express(); // Creating a Bitcoin Lightning payment request app.get("/request", async (req, res) => { try { const data = await client.lightningCharges.create({ amount: '100000', callbackUrl: 'https://your-app.com/zbd-callback', description: 'Express + ZBD!', }); res.status(200).json({ data }); } catch (error) { res.status(500).json({ error }); } }); // Send a payment to a Bitcoin Lightning Address app.get("/send", async (req, res) => { try { const data = await client.lightningAddress.sendPayment({ lnAddress: "andreneves@zbd.gg", // Who is the recipient? amount: "100000", // 100 satoshis (100,000 msats) comment: "Express + ZBD!", }); res.status(200).json({ data }); } catch (error) { res.status(500).json({ error }); } }); app.listen(3000, () => { console.log("Express server w/ ZBD listening on https://example.com"); }); ``` Run the following command to start your Express.js server: ```bash yarn theme={null} yarn start ``` ```bash npm theme={null} npm start ``` Opening your browser to the following URL: `https://example.com/request` should return a JSON response with a payment request. You can also test this using curl command: ```bash theme={null} curl https://example.com/request ``` You're looking for the `data.invoice.request` property in the JSON response. It starts with `lnbc1` and is the payment request anyone in the Bitcoin Lightning Network can use to pay you. ``` lnbc1u1pjdlax9pp5t7jhkd7h2wntd4f2v7xp22dknmjxp0q8nm7hfcny4p7a5mr7x3rsdp9f4hkueteypshggrfde6x2unwv46zqumsv4jkgcqzzsxqzjcsp5dsayu6m6632p28rnkeeqsr7d54amrkv6wh46yrv42gdgca8xl8gs9qyyssqgj2zrkax733rzulfkzc5mqsr8fpwrva82stpa7e0frw32722trv37jlq8mvlqfp8y75lr6mz63zd7qnxar8hhsehuy22pvfq6wjxwqqqa60lx3 ``` Charges and payment requests are usually shown to users as QR codes that can be scanned by mobile apps (e.g. [ZBD](https://zbd.one/download)). Read [Callbacks](/payments/api/callbacks) to understand how to receive updates about your payment asynchronously. Opening your browser to the following URL: `https://example.com/send` should return a JSON response with the payment sent message. You can also test this using curl command: ```bash theme={null} curl https://example.com/send ``` You're looking for the `status` of `completed` to know that the payment settled successfully. Payments in the Lightning Network are asynchronous so you may see a response stating the payment is `processing`. This is expected -- use the `callbackUrl` property to receive updates about your payments. ## 3. Try it yourself You can now send and receive instant Bitcoin payments using Express.js + ZBD! See the full source code. # Next.js Source: https://docs.zbdpay.com/payments/sdk/typescript/next Learn how to use the ZBD with Next.js and our Playground Starter Kit. ## Playground Starter Kit ZBD + Next.js Playground The ZBD + Next.js Playground Starter Kit is an application codebase that allows you to quickly get started with ZBD and Next.js. It includes two main sections: a ZBD API Playground and a Starter Kit for ZBD-powered Next.js applications. Open the ZBD + Next.js Playground View the source code. } href="https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fzebedeeio%2Fnextjs-zebedee-starter&env=ZBD_API_KEY&envDescription=Your%20ZBD%20project%20API%20key&demo-title=ZBD%20%2B%20Next.js%20Starter&demo-description=Starter%20kit%20for%20using%20ZBD%20API%20with%20Next.js%20fullstack%20applications&demo-url=https%3A%2F%2Fnextjs-zebedee-starter.vercel.app%2F&demo-image=https%3A%2F%2Fi.imgur.com%2FNf8wRgv.png"> 1-click deploy your own instance. ## Next.js To use ZBD with Next.js and complete this guide, you will need the following: * [ZBD Project with a Live API key](/get-started/api-keys) ### 1. Create a Next.js project Start with a brand new Next.js project. To begin run the following command and walk through the initializing steps: ```bash theme={null} npx create-next-app@latest ``` ### 2. Install @zbdpay/payments-sdk Node.js SDK Install ZBD: ```bash yarn theme={null} yarn add @zbdpay/payments-sdk ``` ```bash npm theme={null} npm install @zbdpay/payments-sdk ``` ```bash pnpm theme={null} pnpm add @zbdpay/payments-sdk ``` ### 3. Create Send and Receive API routes Create a new file `/app/api/receive/route.ts` and add the following code to create an API route that will receive instant Bitcoin payments: ```js theme={null} import { NextResponse } from 'next/server'; import ZbdPayments from '@zbdpay/payments-sdk'; const ZBD_API_KEY = 'b7YW3s2JzZKGcXjIf5Dqof8wjKT2RuWr8'; // dummy key const client = new ZbdPayments({ apikey: ZBD_API_KEY, }); export async function POST() { try { const data = await client.lightningCharges.create({ amount: '100000', callbackUrl: 'https://your-app.com/zbd-callback', description: 'Next.js + ZBD!', }); return NextResponse.json(data); } catch (error) { return NextResponse.json({ error }); } } ``` Then create a new file `/app/api/send/route.ts` and add the following code to create an API route that will send Bitcoin Lightning Address payments: ```js theme={null} import { NextResponse } from 'next/server'; import ZbdPayments from '@zbdpay/payments-sdk'; const ZBD_API_KEY = 'b7YW3s2JzZKGcXjIf5Dqof8wjKT2RuWr8'; const client = new ZbdPayments({ apikey: ZBD_API_KEY, }); export async function POST() { try { const data = await client.lightningAddress.sendPayment({ lnAddress: "andreneves@zbd.gg", // Who is the recipient? amount: "100000", // 100 satoshis (100,000 msats) comment: "Next.js + ZBD!", }); return NextResponse.json(data); } catch (error) { return NextResponse.json({ error }); } } ``` ### 4. Run your Next.js server Run the following command to start your Next.js server: ```bash yarn theme={null} yarn dev ``` ```bash npm theme={null} npm run dev ``` Using an API tool like [Postman](https://postman.com), you should be able to make a POST call to this endpoint and receive a JSON response with a payment request: ```bash theme={null} https://example.com/api/request ``` You're looking for the `data.invoice.request` property in the JSON response. It starts with `lnbc1` and is the payment request anyone in the Bitcoin Lightning Network can use to pay you. ``` lnbc1u1pjdlax9pp5t7jhkd7h2wntd4f2v7xp22dknmjxp0q8nm7hfcny4p7a5mr7x3rsdp9f4hkueteypshggrfde6x2unwv46zqumsv4jkgcqzzsxqzjcsp5dsayu6m6632p28rnkeeqsr7d54amrkv6wh46yrv42gdgca8xl8gs9qyyssqgj2zrkax733rzulfkzc5mqsr8fpwrva82stpa7e0frw32722trv37jlq8mvlqfp8y75lr6mz63zd7qnxar8hhsehuy22pvfq6wjxwqqqa60lx3 ``` Charges and payment requests are usually shown to users as QR codes that can be scanned by mobile apps (e.g. [ZBD](https://zbd.one/download)). Read [Callbacks](/payments/api/callbacks) to understand how to receive updates about your payment asynchronously. Using an API tool like [Postman](https://postman.com), you should be able to make a POST call to this endpoint and receive a JSON response with the payment success message: ```bash theme={null} https://example.com/api/send ``` You're looking for the `status` of `completed` to know that the payment settled successfully. Payments in the Lightning Network are asynchronous so you may see a response stating the payment is `processing`. This is expected -- use the `callbackUrl` property to receive updates about your payments. ### 5. Try it yourself You can now send and receive instant Bitcoin payments using Next.js + ZBD! See the full source code. # Node.js Source: https://docs.zbdpay.com/payments/sdk/typescript/node Learn how to send and receive instant Bitcoin payments with Node.js and ZBD. ## Prerequisites To complete this guide, you will need the following: * [ZBD Project with a Live API key](/get-started/api-keys) ## 1. Create a Node.js project Start with a brand new empty directory called `node-example` and run the following command to initiate a Node.js project: ```bash theme={null} npm init -y ``` ## 2. Install @zbdpay/payments-sdk Node.js SDK Install ZBD: ```bash yarn theme={null} yarn add @zbdpay/payments-sdk ``` ```bash npm theme={null} npm install @zbdpay/payments-sdk ``` ```bash pnpm theme={null} pnpm add @zbdpay/payments-sdk ``` ## 3. Send and receive Bitcoin Create a new file called `index.js` and add the following code: ```js theme={null} import ZbdPayments from '@zbdpay/payments-sdk'; const ZBD_API_KEY = 'b7YW3s2JzZKGcXjIf5Dqof8wjKT2RuWr8'; // dummy key const client = new ZbdPayments({ apikey: ZBD_API_KEY, }); (async function () { try { const data = await client.lightningCharges.create({ amount: '100000', callbackUrl: 'https://your-app.com/zbd-callback', description: 'Node.js + ZBD!', }); console.log(data); } catch (error) { console.error(error); } })(); ``` Run the following command to start your Node.js server: ```bash yarn theme={null} yarn start ``` ```bash npm theme={null} npm start ```
You may need to add a `start` script to your `package.json` file such as `node index.js`. You're looking for the `data.invoice.request` property in the JSON response. It starts with `lnbc1` and is the payment request anyone in the Bitcoin Lightning Network can use to pay you. ``` lnbc1u1pjdlax9pp5t7jhkd7h2wntd4f2v7xp22dknmjxp0q8nm7hfcny4p7a5mr7x3rsdp9f4hkueteypshggrfde6x2unwv46zqumsv4jkgcqzzsxqzjcsp5dsayu6m6632p28rnkeeqsr7d54amrkv6wh46yrv42gdgca8xl8gs9qyyssqgj2zrkax733rzulfkzc5mqsr8fpwrva82stpa7e0frw32722trv37jlq8mvlqfp8y75lr6mz63zd7qnxar8hhsehuy22pvfq6wjxwqqqa60lx3 ``` Charges and payment requests are usually shown to users as QR codes that can be scanned by mobile apps (e.g. [ZBD](https://zbd.one/download)). Read [Callbacks](/payments/api/callbacks) to understand how to receive updates about your payment asynchronously. ## 3. Try it yourself You can now send and receive instant Bitcoin payments using Express.js + ZBD! See the full source code. # Receiving instant Bitcoin payments with Supabase Source: https://docs.zbdpay.com/payments/sdk/typescript/supabase/receive Learn how to receive Bitcoin using Supabase Edge Functions. ## Prerequisites To complete this guide, you will need the following: * [ZBD Project with a Live API key](/get-started/api-keys) * [Supabase account](https://supabase.com/) + [Supabase CLI installed](https://supabase.com/docs/guides/cli#installation) ## 1. Create a Supabase Function To create a Supabase Edge Function you must run the following command locally: ```bash theme={null} supabase functions new zbd-receive ``` This will create a `/supabase/functions/zbd-receive` folder structure in your project. ## 2. Write the Edge Function Use the code below as a starting point for your handler function. You will need to replace the `ZBD_API_KEY` with your own ZBD Project's API key. ```typescript theme={null} import { serve } from "https://deno.land/std@0.168.0/http/server.ts" const ZBD_API_KEY = "b7Ya3s2JZKZcXXX2Dqf8wjKTZZZRuWr8"; const zbdReceive = async (_request: Request): Promise => { const res = await fetch("https://api.zbdpay.com/v0/charges", { method: "POST", headers: { "Content-Type": "application/json", "apikey": `${ZBD_API_KEY}`, }, body: JSON.stringify({ amount: '100000', // 100 satoshis (100,000 msats) -- ~$0.03 description: 'Money at internet speed', // What is this payment request for? }), }); const data = await res.json(); return new Response(JSON.stringify(data), { status: 200, headers: { "Content-Type": "application/json", }, }); }; serve(zbdReceive); ``` ## 3. Receive payment locally To run this Supabase Edge Function locally you can spin up your Supabase instance using the following command. *You may already have this running at this stage.* ```bash theme={null} supabase functions start ``` Then you can run the following command to start your serverless function: ```bash theme={null} supabase functions serve zbd-receive --no-verify-jwt ``` Note that we add the `--no-verify-jwt` flag to the command to disable JWT verification. This is because we are not passing a JWT token to the function when we call it. **This is not recommended for production use.** Supabase CLI will output a HTTP URL endpoint that you can use to test your function by issuing a POST request to that resource. ## 4. Deploying to Supabase Edge After testing it locally, you can deploy your function to Supabase Edge using the following command. *You will need to enter your Supabase project ID to deploy.* ```bash theme={null} supabase functions deploy zbd-receive ``` Once you deploy you will receive a URL that you can use to view that function in production on Supabase's Web Dashboard: Supabase Edge Functions dashboard Opening your browser (or another HTTP client) to the URL provided by Supabase: `https://xxxxxxxxxxxxx.supabase.co/functions/v1/zbd-receive` should return a JSON response with the payment request details. You can also test this using curl command: ```bash theme={null} curl https://xxxxxxxxxxxxx.supabase.co/functions/v1/zbd-receive ``` You're looking for the `data.invoice.request` property in the JSON response. It starts with `lnbc1` and is the payment request anyone in the Bitcoin Lightning Network can use to pay you. ``` lnbc1u1pjdlax9pp5t7jhkd7h2wntd4f2v7xp22dknmjxp0q8nm7hfcny4p7a5mr7x3rsdp9f4hkueteypshggrfde6x2unwv46zqumsv4jkgcqzzsxqzjcsp5dsayu6m6632p28rnkeeqsr7d54amrkv6wh46yrv42gdgca8xl8gs9qyyssqgj2zrkax733rzulfkzc5mqsr8fpwrva82stpa7e0frw32722trv37jlq8mvlqfp8y75lr6mz63zd7qnxar8hhsehuy22pvfq6wjxwqqqa60lx3 ``` Charges and payment requests are usually shown to users as QR codes that can be scanned by mobile apps (e.g. [ZBD](https://zbd.one/download)). Read [Callbacks](/payments/api/callbacks) to understand how to receive updates about your payment asynchronously. ## 5. Try it yourself You can now begin receiving instant Bitcoin payments on the edge with Supabase + ZBD! See the full source code. # Sending instant Bitcoin payments with Supabase Source: https://docs.zbdpay.com/payments/sdk/typescript/supabase/send Learn how to send Bitcoin using Supabase Edge Functions. ## Prerequisites To complete this guide, you will need the following: * [ZBD Project with a Live API key](/get-started/api-keys) * [Supabase account](https://supabase.com/) + [Supabase CLI installed](https://supabase.com/docs/guides/cli#installation) ## 1. Create a Supabase Function To create a Supabase Edge Function you must run the following command locally: ```bash theme={null} supabase functions new zbd-send ``` This will create a `/supabase/functions/zbd-send` folder structure in your project. ## 2. Write the Edge Function Use the code below as a starting point for your handler function. You will need to replace the `ZBD_API_KEY` with your own ZBD Project's API key. ```typescript theme={null} import { serve } from "https://deno.land/std@0.168.0/http/server.ts" const ZBD_API_KEY = "b7Ya3s2JZKZcXXX2Dqf8wjKTZZZRuWr8"; const zbdSend = async (_request: Request): Promise => { const res = await fetch("https://api.zbdpay.com/v0/ln-address/send-payment", { method: "POST", headers: { "Content-Type": "application/json", "apikey": `${ZBD_API_KEY}`, }, body: JSON.stringify({ lnAddress: 'andre@zbd.gg', // Who is the recipient of the payment? amount: '100000', // 100 satoshis (100,000 msats) -- ~$0.03 comment: 'Money at internet speed', // What is this payment for? }), }); const data = await res.json(); return new Response(JSON.stringify(data), { status: 200, headers: { "Content-Type": "application/json", }, }); }; serve(zbdSend); ``` ## 3. Send payment locally In order to successfully send payments through the API, you must have an active balance in the ZBD Project you are using. [Learn more about depositing funds into a ZBD Project wallet](/get-started/add-funds). If you do not have funds in the ZBD Project you are using, you will receive a 4xx error from the API stating insufficient funds. To run this Supabase Edge Function locally you can spin up your Supabase instance using the following command. *You may already have this running at this stage.* ```bash theme={null} supabase functions start ``` Then you can run the following command to start your serverless function: ```bash theme={null} supabase functions serve zbd-send --no-verify-jwt ``` Note that we add the `--no-verify-jwt` flag to the command to disable JWT verification. This is because we are not passing a JWT token to the function when we call it. **This is not recommended for production use.** Supabase CLI will output a HTTP URL endpoint that you can use to test your function by issuing a POST request to that resource. ## 4. Deploying to Supabase Edge After testing it locally, you can deploy your function to Supabase Edge using the following command. *You will need to enter your Supabase project ID to deploy.* ```bash theme={null} supabase functions deploy zbd-send ``` Once you deploy you will receive a URL that you can use to view that function in production on Supabase's Web Dashboard: Supabase Edge Functions dashboard Opening your browser (or another HTTP client) to the URL provided by Supabase: `https://xxxxxxxxxxxxx.supabase.co/functions/v1/zbd-send` should return a JSON response with the payment sent message. You can also test this using curl command: ```bash theme={null} curl https://xxxxxxxxxxxxx.supabase.co/functions/v1/zbd-send ``` You're looking for the `status` of `completed` to know that the payment settled successfully. Payments in the Lightning Network are asynchronous so you may see a response stating the payment is `processing`. This is expected -- use the `callbackUrl` property to receive updates about your payments. ## 5. Try it yourself You can now begin sending instant Bitcoin payments on the edge with Supabase + ZBD! See the full source code. # Receiving instant Bitcoin payments on Vercel Source: https://docs.zbdpay.com/payments/sdk/typescript/vercel/receive Learn how to receive Bitcoin using Vercel Edge Functions. ## Prerequisites To complete this guide, you will need the following: * [ZBD Project with a Live API key](/get-started/api-keys) * [Vercel account](https://vercel.com/signup) + [Vercel CLI installed](https://vercel.com/docs/cli#installing-vercel-cli) ## 1. Create a Next.js Project Follow the prompts on the create-next-app CLI to create a new project, and then change into the directory of your project. ```bash theme={null} yarn create next-app ``` ```bash theme={null} cd ``` ## 2. Write an Edge Function For this guide we will be making use of the [App Router](https://nextjs.org/docs/app/building-your-application/routing/route-handlers) inside of Next.js. Create a new file in the `app/api/request/route.ts` that creates a Bitcoin Lightning Charge (payment request) with the following code: ```javascript app/api/request/route.ts theme={null} import { NextResponse } from 'next/server'; export const runtime = 'edge'; export const dynamic = 'force-dynamic'; const ZBD_BASE_URL = 'https://api.zbdpay.com'; const ZBD_API_KEY = 'b7YW3s2JzZKGcXjIf5Dqof8wjKT2RuWr8'; export async function GET() { const res = await fetch(`${ZBD_BASE_URL}/v0/charges`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'apikey': `${ZBD_API_KEY}`, }, body: JSON.stringify({ amount: '100000', // 100 satoshis (100,000 msats) -- ~$0.03 description: 'Money at internet speed', // What is this payment request for? }), }); if (res.ok) { const data = await res.json(); return NextResponse.json(data); } } ``` ## 3. Create payment request locally Run function locally: ```bash theme={null} npx next dev ``` Opening your browser to the following URL: `https://example.com/api/request` should return a JSON response with a payment request. You can also test this using curl command: ```bash theme={null} curl https://example.com/api/request ``` You're looking for the `data.invoice.request` property in the JSON response. It starts with `lnbc1` and is the payment request anyone in the Bitcoin Lightning Network can use to pay you. ``` lnbc1u1pjdlax9pp5t7jhkd7h2wntd4f2v7xp22dknmjxp0q8nm7hfcny4p7a5mr7x3rsdp9f4hkueteypshggrfde6x2unwv46zqumsv4jkgcqzzsxqzjcsp5dsayu6m6632p28rnkeeqsr7d54amrkv6wh46yrv42gdgca8xl8gs9qyyssqgj2zrkax733rzulfkzc5mqsr8fpwrva82stpa7e0frw32722trv37jlq8mvlqfp8y75lr6mz63zd7qnxar8hhsehuy22pvfq6wjxwqqqa60lx3 ``` Charges and payment requests are usually shown to users as QR codes that can be scanned by mobile apps (e.g. [ZBD](https://zbd.one/download)). Read [Callbacks](/payments/api/callbacks) to understand how to receive updates about your payment asynchronously. ## 4. Create payment request in production Deploy your project to Vercel: ```bash theme={null} vercel ``` Opening your browser to the following URL: `https://project-name.vercel.app/api/request` should now return this in production. You can also test this using curl command: ```bash theme={null} curl https://project-name.vercel.app/api/request ``` ## 5. Try it yourself You can now begin receiving instant Bitcoin payments on the edge with Vercel + ZBD! See the full source code. # Sending instant Bitcoin payments on Vercel Source: https://docs.zbdpay.com/payments/sdk/typescript/vercel/send Learn how to send Bitcoin using Vercel Edge Functions. ## Prerequisites To complete this guide, you will need the following: * [ZBD Project with a Live API key](/get-started/api-keys) * [Vercel account](https://vercel.com/signup) + [Vercel CLI installed](https://vercel.com/docs/cli#installing-vercel-cli) ## 1. Create a Next.js Project Follow the prompts on the create-next-app CLI to create a new project, and then change into the directory of your project. ```bash theme={null} yarn create next-app ``` ```bash theme={null} cd ``` ## 2. Write an Edge Function For this guide we will be making use of the [App Router](https://nextjs.org/docs/app/building-your-application/routing/route-handlers) inside of Next.js. Create a new file in the `app/api/send/route.ts` that makes a payment to a [Lightning Address](/payments/glossary#lightning-address) (e.g. [andre@zbd.gg](mailto:andre@zbd.gg)) with the following code: ```javascript app/api/send/route.ts theme={null} import { NextResponse } from 'next/server'; export const runtime = 'edge'; export const dynamic = 'force-dynamic'; const ZBD_BASE_URL = 'https://api.zbdpay.com'; const ZBD_API_KEY = 'b7YW3s2JzZKGcXjIf5Dqof8wjKT2RuWr8'; export async function GET() { const res = await fetch(`${ZBD_BASE_URL}/v0/ln-address/send-payment`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'apikey': `${ZBD_API_KEY}`, }, body: JSON.stringify({ lnAddress: 'andre@zbd.gg', // Who is the recipient of the payment? amount: '100000', // 100 satoshis (100,000 msats) -- ~$0.03 comment: 'Money at internet speed', // What is this payment for? }), }); if (res.ok) { const data = await res.json(); return NextResponse.json(data); } } ``` ## 3. Send payment locally In order to successfully send payments through the API, you must have an active balance in the ZBD Project you are using. [Learn more about depositing funds into a ZBD Project wallet](/get-started/add-funds). If you do not have funds in the ZBD Project you are using, you will receive a 4xx error from the API. Run function locally: ```bash theme={null} npx next dev ``` Opening your browser to the following URL: `https://example.com/api/send` should return a JSON response with the payment sent message. You can also test this using curl command: ```bash theme={null} curl https://example.com/api/send ``` You're looking for the `status` of `completed` to know that the payment settled successfully. Payments in the Lightning Network are asynchronous so you may see a response stating the payment is `processing`. This is expected -- use the `callbackUrl` property to receive updates about your payments. ## 4. Send payment in production Deploy your project to Vercel: ```bash theme={null} vercel ``` Opening your browser to the following URL: `https://project-name.vercel.app/api/send` should now return this in production. You can also test this using curl command: ```bash theme={null} curl https://project-name.vercel.app/api/send ``` ## 5. Try it yourself You can now begin sending instant Bitcoin payments on the edge with Vercel + ZBD! See the full source code.