---
name: Sezzle
description: Use when integrating buy-now-pay-later (BNPL) payment options into eCommerce platforms, building custom checkout flows, managing orders and refunds, tokenizing customers for recurring payments, or implementing virtual card payments. Agents should reach for this skill when working with Sezzle API integration, SDK implementation, webhook configuration, order lifecycle management, or troubleshooting payment processing issues.
metadata:
    mintlify-proj: sezzle
    version: "1.0"
---

# Sezzle Skill Reference

## Product Summary

Sezzle is a buy-now-pay-later (BNPL) payment platform that allows merchants to offer flexible installment payment options to customers. Agents use Sezzle to integrate payment processing into eCommerce sites via direct API integration, JavaScript SDK, or pre-built platform plugins (Shopify, WooCommerce, Magento 2, etc.). 

**Key resources:**
- API Gateway: `https://gateway.sezzle.com/v2` (production) or `https://sandbox.gateway.sezzle.com/v2` (sandbox)
- Dashboard: `https://dashboard.sezzle.com/merchant` (production) or `https://sandbox.dashboard.sezzle.com/merchant` (sandbox)
- JavaScript SDK: `https://checkout-sdk.sezzle.com/checkout.min.js`
- API Keys: Retrieved from Merchant Dashboard > Settings > API Keys
- Authentication: All API calls require bearer token from `/v2/authentication` endpoint

## When to Use

Reach for this skill when:
- Building or modifying a direct API integration with Sezzle checkout
- Implementing the JavaScript SDK for in-context checkout (popup, iframe, or redirect)
- Configuring webhooks to receive order status updates (authorized, captured, refunded)
- Managing order lifecycle: capturing, releasing, refunding, or reauthorizing payments
- Tokenizing customers for recurring or subscription payments
- Implementing virtual card payments (card data delivered to payment processor)
- Troubleshooting failed checkouts, authentication errors, or payment processing issues
- Testing integration in sandbox environment before going live
- Migrating from v1 API to v2 API (v1 is deprecated)

## Quick Reference

### API Endpoints (v2)

| Task | Endpoint | Method |
|------|----------|--------|
| Get auth token | `/v2/authentication` | POST |
| Create session | `/v2/session` | POST |
| Get session | `/v2/session/{uuid}` | GET |
| Get order | `/v2/order/{order_uuid}` | GET |
| Capture payment | `/v2/order/{order_uuid}/capture` | POST |
| Release funds | `/v2/order/{order_uuid}/release` | POST |
| Refund payment | `/v2/order/{order_uuid}/refund` | POST |
| Reauthorize | `/v2/order/{order_uuid}/reauthorize` | POST |
| Upcharge | `/v2/order/{order_uuid}/upcharge` | POST |
| Create webhook | `/v2/webhooks` | POST |
| List webhooks | `/v2/webhooks` | GET |
| Tokenize customer | `/v2/session` (with `customer.tokenize: true`) | POST |
| Pre-approve customer | `/v2/token/{token}/customer/preapprove` | POST |

### JavaScript SDK Configuration

```javascript
const checkoutSdk = new Checkout({
  mode: "popup",           // popup, iframe, or redirect
  publicKey: "sz_pub_...", // from dashboard
  apiMode: "sandbox",      // sandbox or live
  apiVersion: "v2"         // use v2
});
```

### Webhook Events to Subscribe

- `order.authorized` — order authorized (AUTH intent)
- `order.captured` — payment captured
- `order.refunded` — refund processed
- `customer.tokenized` — customer approved for tokenization
- `dispute.merchant_input_requested` — dispute requires merchant response
- `dispute.closed.*` — dispute resolution events

### Test Data (Sandbox Only)

| Item | Value |
|------|-------|
| OTP (phone/email) | `123123` |
| Test Visa | `4242424242424242` (any CVC, any future date) |
| Test Mastercard | `5555555555554444` (any CVC, any future date) |
| Test Bank (USD) | Routing: `110000000`, Account: `000123456789` |
| Test Bank (CAD) | Institution: `000`, Transit: `11000`, Account: `000123456789` |

### Order Intent Options

| Intent | Behavior | Use Case |
|--------|----------|----------|
| `CAPTURE` | Funds captured immediately after checkout | Most merchants; default |
| `AUTH` | Only authorize; capture later via API | Inventory validation needed; ship-on-capture model |

### Authorization Expiration

- Default: 30 minutes (Shopify: 7 days)
- Maximum: 7 days
- Configure in Merchant Dashboard > Settings > Payment Captures
- If not captured before expiration, authorization is released and order deleted

## Decision Guidance

### When to Use Direct API vs. SDK vs. Platform Plugin

| Scenario | Approach | Reason |
|----------|----------|--------|
| Custom checkout, full control needed | Direct API | Maximum flexibility; manage session/order lifecycle yourself |
| Quick integration, in-context checkout | JavaScript SDK | Handles UI/UX; popup/iframe modes; less code |
| Shopify, WooCommerce, Magento 2, etc. | Platform plugin | Pre-built, tested; minimal configuration |
| Virtual card (credit card form) | Virtual Card SDK | Integrates with existing payment processors |

### When to Use AUTH vs. CAPTURE Intent

| Condition | Intent | Reason |
|-----------|--------|--------|
| Inventory must be validated post-checkout | `AUTH` | Avoid capturing if item goes out of stock |
| Regulatory requirements before charging | `AUTH` | Comply with compliance checks |
| Ship-on-capture model | `AUTH` | Charge only when order ships |
| Standard eCommerce (capture immediately) | `CAPTURE` | Simplest flow; funds secured immediately |

### When to Use Webhooks vs. Polling

| Approach | Use Case |
|----------|----------|
| Webhooks | Real-time order updates; reliable server-to-server channel; subscribe to events |
| Polling | Reconciliation fallback; verify webhook delivery; check tokenization approval status |

## Workflow

### 1. Set Up Authentication

1. Log in to Merchant Dashboard (production or sandbox)
2. Navigate to Settings > API Keys
3. Copy public and private keys (use Copy icon to avoid typos)
4. Store keys securely (never commit to version control)
5. Call `/v2/authentication` with public/private keys to get bearer token
6. Token expires in 120 minutes; refresh before expiration
7. Include token in `Authorization: Bearer {token}` header for all subsequent API calls

### 2. Create a Session (Direct API)

1. Prepare order object with:
   - `reference_id`: unique merchant order ID (alphanumeric, dashes, underscores only)
   - `order_amount`: total in cents and currency code (USD/CAD)
   - `description`: order description
   - `intent`: `AUTH` or `CAPTURE`
   - `items`: array of purchased items (name, sku, quantity, price)
2. Include customer info if available (email, phone, addresses)
3. POST to `/v2/session` with auth token
4. Response includes `order.uuid` and `order.checkout_url`
5. Redirect customer to `checkout_url`
6. Customer completes Sezzle checkout
7. Sezzle redirects to `complete_url` (or `cancel_url` if cancelled)

### 3. Capture Payment (if AUTH intent used)

1. After customer completes checkout, receive `order_uuid`
2. Validate order in your system (inventory, fraud checks, etc.)
3. POST to `/v2/order/{order_uuid}/capture` with:
   - `capture_amount`: amount in cents and currency
   - `partial_capture`: true for partial, false for full
4. Response confirms capture status
5. If capture fails, order authorization remains valid until expiration

### 4. Handle Refunds

1. Customer requests return/cancellation
2. POST to `/v2/order/{order_uuid}/refund` with:
   - `amount`: refund amount in cents (or omit for full refund)
   - `refund_id`: unique refund identifier
   - `refund_reason`: reason for refund
3. Response confirms refund processed
4. Refund appears in customer's Sezzle account

### 5. Set Up Webhooks

1. Identify events to subscribe: `order.authorized`, `order.captured`, `order.refunded`, `customer.tokenized`, etc.
2. POST to `/v2/webhooks` with:
   - `url`: your endpoint to receive webhooks
   - `events`: array of event types
3. Sezzle sends POST requests to your URL when events occur
4. Verify webhook authenticity (check signature if provided)
5. Respond with 200 OK to acknowledge receipt
6. Implement retry logic on your end for failed webhook processing

### 6. Tokenize a Customer (Recurring Payments)

1. Create session with `customer.tokenize: true` and order object
2. Customer completes checkout and approves tokenization
3. Receive `customer.tokenized` webhook with customer UUID
4. Store customer UUID in your database
5. For future orders, create session with stored customer UUID
6. Customer skips checkout; order processes automatically
7. Use `preapprove` endpoint to verify customer approval before charging

## Common Gotchas

- **Token expiration**: Tokens expire in 120 minutes. Refresh proactively; don't wait for 401 errors.
- **API key mismatch**: Sandbox keys only work with sandbox gateway; production keys only with production. Verify environment matches.
- **Order amount too low**: Minimum order is $1.00 (100 cents); some merchants have higher minimums. Check error message for exact threshold.
- **Missing shipping address**: Long Term Lending program requires complete, valid shipping address (no P.O. boxes). Include shipping_address in customer object.
- **Authorization expiration**: If using AUTH intent, capture before expiration or funds are released and order deleted. Default is 30 minutes.
- **Partial capture without full capture**: If you partially capture, remaining amount is still authorized. Release explicitly if not capturing remainder.
- **Webhook not received**: Subscribe to `customer.tokenized` before going live or you won't be notified of approvals. Use polling as fallback.
- **PCI scope with virtual card**: Manual virtual card integration delivers full card data to frontend. Use tokenization option (`card_response_format: "token"`) to reduce PCI exposure.
- **Checkout URL expires**: Session checkout URLs expire after 30 minutes. Create session at moment customer clicks checkout, not earlier.
- **Reference ID format**: Must be alphanumeric, dashes, underscores only. No spaces or special characters.
- **Currency mismatch**: All amounts in order must use same currency code. Verify order_amount, items, tax, shipping, discounts all match.
- **Sandbox OTP**: Always `123123` in sandbox; never actually sent. Don't expect SMS/email in sandbox.

## Verification Checklist

Before submitting work with Sezzle integration:

- [ ] Authentication token obtained and included in all API requests
- [ ] API keys match environment (sandbox keys for sandbox, production for production)
- [ ] Order reference_id is unique and contains only alphanumeric, dashes, underscores
- [ ] Order amount is in cents and meets minimum threshold ($1.00 / 100 cents)
- [ ] All amounts (order, items, tax, shipping, discounts) use same currency code
- [ ] Customer email included (improves checkout experience)
- [ ] For AUTH intent: capture logic implemented before authorization expires
- [ ] For CAPTURE intent: no additional capture call needed
- [ ] Webhooks subscribed to required events (at minimum: `order.captured`, `order.refunded`)
- [ ] Webhook endpoint responds with 200 OK
- [ ] Error handling implemented for API failures (check `code`, `location`, `message`, `debug_uuid`)
- [ ] Tested in sandbox with test data before going live
- [ ] Sensitive data (API keys, tokens) not logged or exposed in client-side code
- [ ] Redirect URLs (complete_url, cancel_url) are valid and accessible
- [ ] For virtual card: tokenization option used if PCI scope reduction needed
- [ ] For tokenization: `customer.tokenized` webhook subscribed or polling implemented

## Resources

- **Comprehensive navigation**: https://docs.sezzle.com/llms.txt
- **API Reference**: https://docs.sezzle.com/docs/api/intro
- **Direct Integration Guide**: https://docs.sezzle.com/docs/guides/direct/introduction
- **Sandbox Testing**: https://docs.sezzle.com/docs/api/environments
- **Merchant Support**: https://merchant-help.sezzle.com/hc/en-us

---

> For additional documentation and navigation, see: https://docs.sezzle.com/llms.txt