Orders, payments, subscriptions, and refunds in one API. Built by ex-Square engineers. Join the waitlist to get early access.
Don't want to wait? Feed this document to your AI agent and start building against our sandbox API right now. Includes a pre-provisioned API key.
# Flint Pay — Sandbox API Reference (llm.txt)
> This document is designed for AI agents and LLMs integrating with the Flint Pay Sandbox API.
> All fields use camelCase in JSON. All requests are POST with Content-Type: application/json.
## Base URL & Auth
```
Base: https://api.staging.withflintpay.com
Auth: Authorization: Bearer <your_sandbox_api_key>
Path: POST /<package>.<Service>/<Method>
```
### Sandbox Demo Key (read/write to all resources)
```
flint_test_9cf074b6f47381d2cad56992bcb1abf3915940f84ff1158ce3db56503208e3ed
```
## Money Fields
Integer cents with currency code. Three types:
- `Money`: amount >= 0 (most fields)
- `PositiveMoney`: amount >= 1 (tips, refund amounts)
- `SignedMoney`: can be negative (balances, deltas)
```json
{ "amount": 1500, "currency": "USD" } // = $15.00
```
## ID Prefixes
`ord_` order, `li_` line item, `cus_` customer, `pi_` payment intent, `pm_` payment method, `item_` catalog item, `cpn_` coupon, `ref_` refund, `sub_` subscription, `plan_` plan, `cs_` checkout session, `mer_` merchant
Embedded sub-objects (tip, applied_discount) have no prefix.
## Error Responses
Errors return a Connect RPC status code with a structured body:
```json
{
"code": "FIELD_REQUIRED",
"message": "The 'order_id' field is required",
"field": "order_id"
}
```
Common status codes:
- `invalid_argument` (400): validation errors — FIELD_REQUIRED, INVALID_ID, CURRENCY_MISMATCH, ORDER_CLOSED, COUPON_EXPIRED, COUPON_NOT_STACKABLE, LINE_ITEM_INVALID_QUANTITY
- `not_found` (404): RESOURCE_NOT_FOUND, COUPON_NOT_FOUND, DISCOUNT_NOT_FOUND
- `already_exists` (409): ORDER_CONFLICT (concurrent modification — refetch and retry)
- `unauthenticated` (401): missing/invalid API key
- `permission_denied` (403): insufficient scope or wrong merchant
- `unavailable` (503): PAYMENT_PROCESSOR_ERROR (retryable), PAYMENT_FAILED (not retryable without new payment method)
## Pagination (all List endpoints)
`pageSize`: 1-100 (default 20). `pageToken`: opaque string from `nextPageToken` in previous response. Empty `nextPageToken` = no more pages.
## FieldMask Updates
Update RPCs use `updateMask` (camelCase, comma-separated paths). Only fields in the mask are modified:
```json
{
"orderId": "ord_xxx",
"updateMask": "buyerNote,metadata",
"buyerNote": "Rush order",
"metadata": { "key": "value" }
}
```
## Metadata (all resources)
Max 50 keys. Key: 1-255 chars. Value: max 2048 chars.
---
## Orders — `flint.v1.commerce.OrderService`
### Methods
| Method | Description |
|--------|-------------|
| CreateOrder | Create order. Optional: `customerId`, `lineItems`, `tips`, `discounts`, `buyerNote`, `merchantNote` |
| GetOrder | Get by `orderId` |
| UpdateOrder | Update `customerName`, `buyerNote`, `merchantNote`, `metadata`. Requires `updateMask` |
| ListOrders | Filter: `customerId`, `status`, `orderNumber`, `source`, `subscriptionId`, `query`, date ranges. Sort: `CREATED_AT`, `UPDATED_AT`, `DUE_MONEY` |
| CloseOrder | Close an OPEN order with no balance |
| PayOrder | Confirm all attached payment intents. Fields: `orderId`, optional `paymentIntentIds`, `idempotencyKey` |
| AddLineItems | Add `lineItems` to order |
| UpdateLineItem | Update by `orderLineItemId`. Catalog-linked: only `quantity`. Ad-hoc: `quantity`, `name`, `unitPriceMoney`, etc. |
| RemoveLineItems | Remove by `orderLineItemIds` (not `lineItemIds`) |
| AddTips | Add tips to order |
| UpdateTip | Update by `orderTipId` |
| RemoveTips | Remove by `orderTipIds` (not `tipIds`) |
| ApplyCoupon | Apply by `couponCode` OR `couponId` (oneof, exactly one required) |
| RemoveDiscounts | Remove by `appliedDiscountIds` (not `discountIds`). Cannot remove redeemed discounts |
| ApplyTax | Apply tax using `taxAddress` (can be a zip code). Must re-run after line item changes |
### Line Item Input
```json
{
"name": "Widget", // required, max 255 chars
"quantity": "1", // required, >= 1, string
"unitPriceMoney": { "amount": 1500, "currency": "USD" }, // required, Money (>= 0)
"itemId": "item_xxx", // optional — links to catalog item
"description": "...", // optional
"sku": "...", // optional
"metadata": {} // optional
}
```
### Tip Input
`oneof tipValue` — exactly one required:
- `amountMoney`: PositiveMoney (>= 1 cent)
- `percent`: whole number 1.0–100.0 (NOT a fraction)
### Discount Input (on CreateOrder)
`oneof source`:
- `coupon`: `{ "couponId": "cpn_xxx" }` or `{ "couponCode": "SAVE10" }`
- `manual`: `{ "name": "...", "amountMoney": {...}, "scope": "DISCOUNT_SCOPE_ORDER" }`
### Order Status & Allowed Mutations
| Status | Allowed |
|--------|---------|
| `OPEN` | All mutations (line items, tips, discounts, payments, close) |
| `PAID` | Refunds and metadata only |
| `PARTIALLY_REFUNDED` | Additional refunds, metadata only |
| `CLOSED`, `REFUNDED` | No mutations |
### Response: Net Amounts
The `netAmounts` object on every Order response:
- `subtotalMoney`: sum of line item gross amounts
- `discountMoney`: sum of applied discounts
- `taxMoney`: sum of taxes
- `tipMoney`: sum of tips
- `paidMoney`: sum of succeeded payments
- `refundedMoney`: sum of succeeded refunds
- `balanceMoney` (SignedMoney): positive = owed, zero = settled, negative = overpaid
Each line item also has computed `grossMoney`, `discountMoney`, `taxMoney`, `netMoney`.
### Source Enum (shared across Orders, PaymentIntents, CheckoutSessions)
`SOURCE_API`, `SOURCE_CHECKOUT`, `SOURCE_VIRTUAL_TERMINAL`, `SOURCE_PAYMENT_LINK`, `SOURCE_POS`, `SOURCE_SUBSCRIPTION`
---
## Customers — `flint.v1.customers.CustomerService`
### Methods
| Method | Description |
|--------|-------------|
| CreateCustomer | Required: `name` (1-255), `email` (valid format). Optional: `phoneNumber`, `billingAddress`, `shippingAddress`, `merchantCustomerId`, `buyerNote` |
| GetCustomer | Get by `customerId` |
| GetCustomerByEmail | Get by `email` (exact match, scoped to merchant) |
| UpdateCustomer | Mutable: `name`, `billingAddress`, `shippingAddress`, `merchantCustomerId`, `buyerNote`, `phoneNumber`, `merchantNote`, `metadata`. Email is IMMUTABLE |
| ListCustomers | Filter: `query` (search name/email/phone), `email` (exact match), date ranges. Sort: `NAME`, `EMAIL`, `CREATED_AT`, `UPDATED_AT` |
### Address Format
```json
{ "line1": "123 Main St", "line2": "Apt 4", "city": "NYC", "state": "NY", "postalCode": "10001", "country": "US" }
```
`country` is 2-char ISO code.
---
## Items — `flint.v1.commerce.ItemService`
### Methods
| Method | Description |
|--------|-------------|
| CreateItem | Required: `name`, `unitPriceMoney` (Money, allows 0). Optional: `type`, `sku`, `description`, `categories`, `imageUrl`, `quantityAvailable`, `enforceInventoryLimit`, `taxable`, `taxCategory` |
| GetItem | Get by `itemId` |
| GetItemBySKU | Get by `sku` (exact match, scoped to merchant) |
| UpdateItem | Mutable via FieldMask: `name`, `description`, `unitPriceMoney`, `sku`, `imageUrl`, `taxable`, `taxCategory`, `enforceInventoryLimit`, `status`, `metadata`. NOT `quantityAvailable` or `categories` |
| DeleteItem | Permanent delete |
| ListItems | Filter: `type`, `status`, `onlyInStock`, `category`, `query` (name/SKU search), date ranges. Sort: `NAME`, `CREATED_AT`, `UPDATED_AT`, `UNIT_PRICE` |
| AdjustInventory | `itemId`, `quantityDelta` (nonzero int, can be negative), optional `note`, `changeReason` |
| AddItemCategories | Add categories by string array |
| RemoveItemCategories | Remove categories by string array |
| ReplaceItemCategories | Replace all categories (empty array clears) |
### Item Enums
- **ItemType**: `ITEM_TYPE_PRODUCT`, `SERVICE`, `FEE`, `DIGITAL`
- **ItemStatus**: `ITEM_STATUS_ACTIVE`, `INACTIVE` (reversible), `DELETED` (permanent)
- **InventoryChangeReason**: `MANUAL_ADJUSTMENT`, `ORDER_FULFILLMENT`, `ORDER_CANCELLATION`, `ORDER_REFUND`, `RECEIVED_STOCK`, `INVENTORY_COUNT`, `DAMAGE`, `THEFT`, `LOSS`
---
## Coupons — `flint.v1.commerce.CouponService`
### Methods
| Method | Description |
|--------|-------------|
| CreateCoupon | Required: `name`, one of `percentOff` (0.01-100.0) or `amountOffMoney`. Optional: `couponCode` (omit = codeless coupon), `maxUses`, `expiresAt`, `isStackable`, `minimumPurchaseAmount`, `limitToItemIds` |
| GetCoupon | Get by `couponId` |
| GetCouponByCode | Get by `couponCode` (returns any status except DELETED) |
| UpdateCoupon | Mutable: `name`, `couponCode`, `maxUses`, `expiresAt`, `status` (`COUPON_MUTABLE_STATUS_ACTIVE`/`DISABLED`), `isStackable`, `minimumPurchaseAmount`, `percentOff`/`amountOffMoney`, `metadata`. NOT `limitToItemIds` (use RPCs below) |
| ListCoupons | Filter: `status`, `query` (name/code search), `limitToItemId`, expiry/date ranges. Sort: `NAME`, `CREATED_AT`, `UPDATED_AT`, `EXPIRES_AT` |
| DeleteCoupon | Permanent delete |
| AddCouponLimitToItems | Add item restrictions |
| RemoveCouponLimitToItems | Remove item restrictions |
| ReplaceCouponLimitToItems | Replace all (empty = universal coupon) |
### Coupon Status (computed, read-only)
`COUPON_STATUS_ACTIVE`, `DISABLED` (merchant-toggled, reversible), `EXPIRED` (past expiresAt), `EXHAUSTED` (usesCount >= maxUses), `DELETED`
Discount value is oneof: set `percentOff` OR `amountOffMoney`, never both.
---
## Payments — `flint.v1.payments.PaymentIntentService`
### Methods
| Method | Description |
|--------|-------------|
| CreatePaymentIntent | Required: `orderId`. Optional: `amountMoney` (omit to auto-derive from order balance), `autoConfirm`, `paymentMethodTypes`, `digitalWallets`, `tipMoney`, `statementDescriptor` (max 22 chars), `receiptEmail`, `paymentMethodId` (saved pm_), `customerId` |
| GetPaymentIntent | Get by `paymentIntentId` |
| UpdatePaymentIntent | Mutable (varies by status). FieldMask: `amountMoney`, `sourceId`, `customerId`, `tipMoney`, `receiptEmail`, `metadata` |
| ConfirmPaymentIntent | Confirm after attaching source. Fields: `paymentIntentId`, optional `sourceId`, `idempotencyKey` |
| CapturePaymentIntent | Capture an authorized payment. Optional `amountMoney` for partial capture |
| ListPaymentIntents | Filter: `status`, `orderId`, `customerId`, `source`, `minAmount`/`maxAmount`, `query`, date ranges. Sort: `CREATED_AT`, `UPDATED_AT`, `AMOUNT` |
| CancelPaymentIntent | Cancel a non-terminal payment intent |
### Payment Status State Machine
```
REQUIRES_PAYMENT_METHOD → REQUIRES_CONFIRMATION → PROCESSING → SUCCEEDED
→ REQUIRES_ACTION (3DS)
→ REQUIRES_CAPTURE (auth-only)
REQUIRES_CAPTURE → SUCCEEDED (via CapturePaymentIntent)
Any non-terminal → CANCELED | EXPIRED (24h timeout)
```
Terminal: `SUCCEEDED`, `CANCELED`, `EXPIRED`
### Mutability by Status
- `REQUIRES_PAYMENT_METHOD`: all fields mutable
- `REQUIRES_CONFIRMATION`: only metadata, customerId, tipMoney, receiptEmail
- `PROCESSING` or terminal: nothing mutable
### Response Fields
Key response fields: `status`, `amountMoney`, `tipMoney`, `paymentMethodLastFour`, `paymentMethodBrand`, `processorDetails.stripe.clientSecret` (needed for frontend Stripe.js), `nextActions` (agent hints for next steps).
### Payment Method Types & Wallets
- **PaymentMethodType**: `PAYMENT_METHOD_TYPE_CARD`, `AFFIRM`, `LINK`
- **DigitalWallet**: `DIGITAL_WALLET_APPLE_PAY`, `GOOGLE_PAY`
- **CardBrand**: `CARD_BRAND_VISA`, `MASTERCARD`, `AMEX`, `DISCOVER`, `DINERS`, `JCB`, `UNIONPAY`
---
## Payment Methods — `flint.v1.payments.PaymentMethodService`
### Methods
| Method | Description |
|--------|-------------|
| SavePaymentMethod | Create a setup intent for `customerId`. Returns `processorDetails.stripe.clientSecret` for frontend `stripe.confirmCardSetup()` |
| GetPaymentMethod | Get by `paymentMethodId`. Card details populated only after Stripe webhook confirms setup |
| ListPaymentMethods | Required: `customerId`. Returns ACTIVE methods by default |
| RemovePaymentMethod | Remove by `paymentMethodId` |
| SetDefaultPaymentMethod | Set default for `customerId`. Must be ACTIVE and belong to that customer |
### Lifecycle
1. `SavePaymentMethod(customerId)` → get `clientSecret`
2. Frontend calls `stripe.confirmCardSetup(clientSecret)`
3. Stripe webhook fires → card details saved
4. `GetPaymentMethod` now returns `card` with `last4`, `brand`, `expMonth`, `expYear`, optional `wallet`
**PaymentMethodStatus**: `ACTIVE`, `EXPIRED`, `REMOVED`
---
## Refunds — `flint.v1.commerce.RefundService`
### Methods
| Method | Description |
|--------|-------------|
| CreateRefund | Target: `orderId` and/or `paymentIntentId` (at least one). Optional: `amountMoney` (omit = full refund). Required: `reason`, `idempotencyKey`. Optional: `reasonMessage` |
| GetRefund | Get by `refundId` |
| UpdateRefund | Only `metadata` is mutable |
| ListRefunds | Filter: `orderId`, `paymentIntentId`, `status`, `customerId`, `reasons`, `minAmount`/`maxAmount`, date ranges. Sort: `CREATED_AT`, `UPDATED_AT`, `AMOUNT` |
### Refund Status
`REFUND_STATUS_PENDING` → `IN_TRANSIT` → `SUCCEEDED` or `FAILED`
### Refund Reason Enum (required)
`REFUND_REASON_DUPLICATE`, `FRAUDULENT`, `REQUESTED_BY_CUSTOMER`, `DEFECTIVE_PRODUCT`, `WRONG_ITEM_SHIPPED`, `NEVER_RECEIVED`, `NOT_AS_DESCRIBED`, `ARRIVED_TOO_LATE`, `CUSTOMER_CHANGED_MIND`, `BETTER_PRICE_FOUND`, `ACCIDENTAL_ORDER`, `OTHER`
---
## Subscriptions — `flint.v1.commerce.SubscriptionService`
### Methods
| Method | Description |
|--------|-------------|
| CreateSubscription | Required: `planId`, `customerId`. Optional: `paymentMethodId` (falls back to customer default), `billingAnchorDay` (1-31, default today) |
| GetSubscription | Get by `subscriptionId` |
| UpdateSubscription | Mutable: `paymentMethodId`, `metadata`. Requires `updateMask` |
| ListSubscriptions | Filter: `status`, `customerId`, `planId` |
| CancelSubscription | Optional `cancelImmediately` (default false = cancel at period end). Returns `contractInfo` if applicable |
| PauseSubscription | Optional `pauseDurationCycles` (omit = indefinite pause) |
| ResumeSubscription | Resume a paused subscription |
### Subscription Status
`SUBSCRIPTION_STATUS_TRIALING`, `ACTIVE`, `PAUSED`, `PAST_DUE`, `CANCELED` (terminal)
### Response Fields
Key fields: `currentPeriodStart`, `currentPeriodEnd`, `nextBillingDate`, `cancelAtPeriodEnd`, `trialEnd`, `pausedAt`, `canceledAt`
---
## Subscription Plans — `flint.v1.commerce.SubscriptionPlanService`
### Methods
| Method | Description |
|--------|-------------|
| CreateSubscriptionPlan | Required: `name`, `billingInterval`, `currency` (3-char ISO). Optional: `billingIntervalCount` (default 1), `lineItems`, `setupFeeMoney`, `trialPeriodDays`, `description`, `contractTermMonths`, `earlyTerminationFeeMoney` |
| GetSubscriptionPlan | Get by `planId` (returns archived plans too) |
| UpdateSubscriptionPlan | Mutable: `name`, `description`, `lineItems`, `setupFeeMoney`, `trialPeriodDays`, `metadata`, `contractTermMonths`, `earlyTerminationFeeMoney`. Immutable: `billingInterval`, `billingIntervalCount`, `currency` |
| ListSubscriptionPlans | Filter: `status`, date ranges. Sort: `NAME`, `CREATED_AT`, `UPDATED_AT` |
| ArchiveSubscriptionPlan | Archive (not delete). Existing subscriptions continue |
### Plan Line Item
Two modes — catalog-linked or ad-hoc:
```json
// Catalog: price resolved from item at billing time
{ "itemId": "item_xxx", "quantity": 1 }
// Ad-hoc: fixed price
{ "name": "Monthly Fee", "unitPriceMoney": { "amount": 2999, "currency": "USD" }, "quantity": 1 }
```
### Billing Interval
`BILLING_INTERVAL_DAILY`, `WEEKLY`, `MONTHLY`, `YEARLY`. Combined with `billingIntervalCount` (e.g., 2 + MONTHLY = every 2 months).
**SubscriptionPlanStatus**: `ACTIVE`, `ARCHIVED`
---
## Checkout Sessions — `flint.v1.checkouts.CheckoutSessionService`
### Methods
| Method | Description |
|--------|-------------|
| CreateCheckoutSession | Oneof: `orderId` (existing order) OR `quickPay` (`{ "name": "...", "amountMoney": {...} }` auto-creates order). Config objects: `theme`, `paymentConfig`, `tipConfig`, `customerConfig`, `legalConfig`, `expirationConfig`, `taxConfig`, `redirects` |
| GetCheckoutSession | Get by `checkoutSessionId`. Response includes `url` (hosted payment page) |
| UpdateCheckoutSession | Only `metadata` is mutable (works in any state including terminal) |
| CloseCheckoutSession | Close with optional `reason` |
| ListCheckoutSessions | Filter: `status`, `orderId`, `source`, `query`, date ranges. Sort: `CREATED_AT`, `UPDATED_AT` |
### Checkout Session Status
`OPEN` → `PAID` (payment succeeded) | `EXPIRED` (timed out) | `CLOSED` (manually closed) | `INVALIDATED` (order modified after session created)
### Key Config Objects
**ExpirationConfig**: `expirationSeconds` (1-86400, default 86400)
**TipConfig**: `isEnabled`, `tipPercentages` (array of 0.01-100.0), `defaultTipPercentage`, `isCustomTipEnabled`, `isSmartTipsEnabled`, `smartTipAmounts`
**CustomerConfig**: `customerId` (auto-fill), `prefilledCustomerInfo`, `enableAddressAutocomplete`
**Redirects**: `successRedirectUrl`, `cancelRedirectUrl`, `onLoadRedirectUrl`
**PaymentConfig**: `allowedPaymentMethodTypes`, `allowedDigitalWallets`, `statementDescriptor`
---
## Settings — `flint.v1.settings.SettingsService`
### Methods
| Method | Description |
|--------|-------------|
| GetSettings | Get raw settings at one scope. Required: `scope` |
| UpdateSettings | Update settings. Config sections are top-level fields (NOT nested under `settings`). Requires `scope` + `updateMask` |
| GetEffectiveSettings | Get merged/inherited settings. Optional `locationId` |
### Scope Hierarchy (most specific wins)
`SETTINGS_SCOPE_ORGANIZATION` < `SETTINGS_SCOPE_MERCHANT` < `SETTINGS_SCOPE_LOCATION`
### Config Sections
- **tipping**: `isEnabled`, `tipPercentages`, `defaultTipPercentage`, `isCustomTipEnabled`, `isSmartTipsEnabled`, `smartTipAmounts`
- **checkout**: `allowedPaymentMethodTypes`, `allowedDigitalWallets`, `isCustomerEmailRequired`, `statementDescriptor` (max 22), `defaultExpirationSeconds`
- **tax**: `isEnabled`
- **receipt**: `headerText`, `footerText`, `isItemized`, `isAutoEmailEnabled`
- **inventory**: `lowStockThreshold` (0 = disabled)
- **branding**: `primaryColor` (hex #RRGGBB), `accentColor`
- **legal**: `termsOfServiceUrl`, `requiresTermsOfService`, `refundPolicyUrl`
- **subscription**: `dunningEndAction` (`CANCEL`/`PAUSE`), `dunningRetryDays` (1-90)
IMPORTANT: config sections go directly on the request, NOT nested under a `settings` key:
```json
// Correct:
{ "scope": "SETTINGS_SCOPE_MERCHANT", "checkout": { "statementDescriptor": "Acme" }, "updateMask": "checkout.statementDescriptor" }
```
---
## Accounts
### Merchants — `flint.v1.accounts.merchants.MerchantService`
| Method | Description |
|--------|-------------|
| GetMerchant | Get merchant details |
| UpdateMerchant | Update merchant profile |
### Users — `flint.v1.accounts.UserService`
| Method | Description |
|--------|-------------|
| ListUsers | List users |
| GetUser | Get user by ID |
### API Keys — `flint.v1.accounts.APIKeyService`
| Method | Description |
|--------|-------------|
| CreateAPIKey | Create a new API key |
| RevokeAPIKey | Revoke an API key |
| ListAPIKeys | List API keys |
---
## Idempotency
RPCs that accept `idempotencyKey` will return the cached response for duplicate requests with the same key. Use UUIDs. Applies to: CreateOrder, CreatePaymentIntent, ConfirmPaymentIntent, CapturePaymentIntent, CreateRefund, PayOrder, CreateCustomer.
## Response Metadata
Every response includes a `meta` object with `requestId` (for debugging) and `idempotencyReplayed` (bool, true if response was from cache).
## Important: merchantId is Server-Derived
Never set `merchantId` in request bodies — it is always derived from the authenticated API key. If provided and mismatched, returns `permission_denied`.
---
## Bug Reports & Feedback
If you encounter unexpected API behavior, errors that don't match this documentation, or missing functionality, report it at:
https://github.com/flint-llc/flintpay-api-feedback/issues
### How to file a good bug report
1. Click "New issue" and select "Bug Report"
2. Fill in all required fields — incomplete reports are closed without review
3. Required fields:
- **Service**: which service the bug is in (e.g. OrderService)
- **Endpoint**: full RPC path (e.g. flint.v1.commerce.OrderService/CreateOrder)
- **Request body**: the exact JSON you sent (remove API keys)
- **Response received**: the full error or unexpected response
- **Expected behavior**: what you expected to happen
4. Check the three preflight boxes confirming it's not a duplicate and no sensitive data is included
### Security vulnerabilities
Do NOT file security issues publicly. Email security@withflintpay.com instead.
### Feature requests
Use the "Feature Request" template on the same repo to suggest new endpoints, fields, or behaviors.
---
## Quick Start Example
### 1. Create a customer
```bash
curl -X POST https://api.staging.withflintpay.com/flint.v1.customers.CustomerService/CreateCustomer \
-H "Content-Type: application/json" \
-H "Authorization: Bearer flint_test_9cf074b6f47381d2cad56992bcb1abf3915940f84ff1158ce3db56503208e3ed" \
-d '{"name": "Jane Doe", "email": "jane@example.com"}'
```
### 2. Create an order with line items
```bash
curl -X POST https://api.staging.withflintpay.com/flint.v1.commerce.OrderService/CreateOrder \
-H "Content-Type: application/json" \
-H "Authorization: Bearer flint_test_9cf074b6f47381d2cad56992bcb1abf3915940f84ff1158ce3db56503208e3ed" \
-d '{
"customerId": "cus_xxx",
"lineItems": [{
"name": "Premium Widget",
"quantity": "1",
"unitPriceMoney": {"amount": 2500, "currency": "USD"}
}]
}'
```
### 3. Create a payment intent (amount auto-derived from order balance)
```bash
curl -X POST https://api.staging.withflintpay.com/flint.v1.payments.PaymentIntentService/CreatePaymentIntent \
-H "Content-Type: application/json" \
-H "Authorization: Bearer flint_test_9cf074b6f47381d2cad56992bcb1abf3915940f84ff1158ce3db56503208e3ed" \
-d '{"orderId": "ord_xxx"}'
```
### 4. Create a refund (full amount)
```bash
curl -X POST https://api.staging.withflintpay.com/flint.v1.commerce.RefundService/CreateRefund \
-H "Content-Type: application/json" \
-H "Authorization: Bearer flint_test_9cf074b6f47381d2cad56992bcb1abf3915940f84ff1158ce3db56503208e3ed" \
-d '{
"orderId": "ord_xxx",
"reason": "REFUND_REASON_REQUESTED_BY_CUSTOMER",
"idempotencyKey": "unique-key-123"
}'
```
### 5. Create a checkout session (quick pay)
```bash
curl -X POST https://api.staging.withflintpay.com/flint.v1.checkouts.CheckoutSessionService/CreateCheckoutSession \
-H "Content-Type: application/json" \
-H "Authorization: Bearer flint_test_9cf074b6f47381d2cad56992bcb1abf3915940f84ff1158ce3db56503208e3ed" \
-d '{
"quickPay": {"name": "One-time charge", "amountMoney": {"amount": 5000, "currency": "USD"}},
"redirects": {"successRedirectUrl": "https://example.com/thanks"}
}'
```
Copy and paste into your AI agent's system prompt or context window to start making API calls.