Accept your first payment

Create a payment link with one API request, open its URL, pay with a test card, and find the payment in your dashboard. You need a Flint account, curl, and a browser. Flint hosts the checkout page, so there is no checkout UI to build, and no real money moves.

Before you start#

No account yet? Request access, or run flint signup in your terminal. flint signup stores its sandbox key in your system keychain and does not print it. To keep working in the terminal, use the CLI command in step 1. To use curl, create a key in the dashboard as described next.

Switch the dashboard to your sandbox. In the dashboard, open the environment menu in the top bar. It shows live or sandbox. Choose your sandbox; every account starts with one named Default Test. A test key belongs to the sandbox that is selected when you create it, and the dashboard shows that sandbox's payments only while it is selected.

Get a test API key. On the API keys page:

  1. Click Create key. A sandbox's first key starts as a Restricted key named Test key, with the permissions an integration needs to take payments, including the ones used here. Keep that selection. Full access grants every permission, but asks you to confirm your identity again before the key is created.
  2. Click Create key in the dialog and copy the key. It starts with flint_test_ and is shown once.

If the sandbox already has a key, the dialog starts at Full access instead. Keep it and confirm your identity when asked, or choose Restricted and limit the key to Capabilities: Read and Payment links: Write.

Authentication explains permissions. If your backend provisions merchants, API & agent onboarding creates the account and its first key instead.

Keep the key on your backend. Every request goes to https://api.withflintpay.com with the key in the Authorization header. Test and live keys share that hostname, and the key decides the mode. Replace YOUR_API_KEY in each command with your key.

If you're signed in to the docs, each request below can run against your sandbox with your test key filled in.

Check that your sandbox can take card payments:

cURL
curl "https://api.withflintpay.com/v1/capabilities?capability=accept_card_payments" \
  -H "Authorization: Bearer YOUR_API_KEY"
Response
{
  "data": [
    {
      "capability": "accept_card_payments",
      "domain": "payments",
      "status": "ready"
    }
  ]
}

status: "ready" means checkout will show a card form. Flint prepares your default sandbox for card payments when you sign up. For a short time after sign-up the status can be pending; wait a minute and run the check again.

Warning:

A 200 response confirms the request worked, not that the sandbox can charge cards. While the capability is pending or blocked, the hosted checkout page says "No payment methods are available for this checkout." and asks the buyer to contact the merchant instead of showing a card form. The response's blocked_reasons and requirements name what is still due. Complete it in the dashboard, then run the check again.

A payment link is a Flint-hosted checkout page with a URL you can share. Create one for a $25 design consultation. Amounts are integers in the currency's minor unit, so 2500 is $25.00. See Money & currency for other currencies.

cURL
curl -X POST https://api.withflintpay.com/v1/payment-links \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Idempotency-Key: first-payment-link-001" \
  -d '{
    "name": "Design consultation",
    "line_items": [{
      "name": "Design consultation",
      "quantity": 1,
      "unit_price_money": {"amount": 2500, "currency": "USD"}
    }],
    "tax": {"enabled": false},
    "tip": {"enabled": false}
  }'

name identifies the link in the dashboard's list of payment links. tax.enabled: false and tip.enabled: false keep tax and the tip prompt off this link, so the total stays $25.00 whatever your checkout settings are. The line item is defined on the link itself, so you don't need a product in your catalog first. To sell from your catalog, pass a product's variant_id or a bundle_id instead, as Pricing line items describes.

Response
{
  "data": {
    "payment_link_id": "pl_1kmn0aExample",
    "url": "https://checkout.withflintpay.com/pay/pl_1kmn0aExample",
    "status": "active",
    "payment_link_type": "standard",
    "completed_count": 0,
    "line_items": [{
      "payment_link_line_item_id": "plli_1kmn0aExample",
      "key": "design-consultation",
      "name": "Design consultation",
      "quantity": 1,
      "unit_price_money": {"amount": 2500, "currency": "USD"}
    }]
  }
}

The link is active, and nothing has been charged. Copy data.url from your response.

Note: Safe to retry

The request carries an Idempotency-Key. If it times out, send it again with the same key and body, and Flint returns the original link instead of creating a second one. To create another link, change the key, for example from 001 to 002. Keys are honored for 24 hours. See Idempotency.

From the CLI#

With the CLI, sign in with flint login or create an account with flint signup. Both keep a sandbox credential in your system keychain, so there is no key to paste. Create the same link and print its URL. These flags leave tax and tips to your checkout settings, which are off for a new account:

Shell
flint payment-links create \
  --name "Design consultation" \
  --item-name "Design consultation" \
  --amount 2500 \
  --currency USD \
  --field data.url

Step 2: pay with a test card#

Open the URL in a browser. Checkout shows a test-mode banner and a $25.00 total. Fill in the buyer details checkout asks for and pay with:

Test cardAny future expiry, any CVC.

Flint processes card payments on Stripe, so Stripe's test cards work here and you don't need a Stripe account. Cards that decline or require 3D Secure are listed in Testing.

After the payment succeeds, checkout shows a receipt. The link stays active, and every buyer who opens the URL gets their own checkout, so you can pay it again.

Step 3: find the payment in your dashboard#

With the same sandbox selected, open Payments in the dashboard. Your $25.00 payment is at the top of the list with the status Succeeded. Open it for the payment's details, including the order it paid. Each completed checkout on a payment link creates its own order, and the order is listed under Orders.

If you ran the requests from the docs, they used your Default Test sandbox. If the payment isn't listed, check the environment menu: a test payment appears only in the sandbox its key belongs to.

Take it into your app#

  • Share the link as is. One payment link takes payment from any number of buyers. Put the same URL in an email, a QR code, or a pricing page. Payment links covers quantities, donations, events, and subscriptions.
  • Use a checkout session for an order your app builds, such as a cart. Your backend creates the order and a checkout session for it, then sends the buyer to the session's URL. Testing walks through that flow with the same test card, and Payment links vs checkout sessions vs invoices compares the options.
  • Fulfill from the order.paid webhook, not from the browser. A buyer can close the tab before the receipt loads. Subscribe to order.paid, verify the signature, fetch the order, and fulfill. Orders from a link carry origin: "payment_link" and the link's metadata. Flint retries a delivery until your endpoint acknowledges it, so make fulfillment safe to repeat. See Webhooks and Fulfill and reconcile.
  • Live mode is the same request with a live key. Same hostname, same body. Going live covers account verification and the cutover.

Next steps#

  • Payment links: reusable links for products, donations, events, and subscriptions, and how to track what each link sold.
  • Checkout sessions: one hosted checkout for one order, with buyer details, payment options, expiration, and appearance.
  • Testing: declines, 3D Secure, refunds, and webhook deliveries in your sandbox.
  • Embedded payments with Stripe Elements: collect the card in your own UI instead of on a hosted page.
  • SDKs and CLI: call the same API from @flintpay/node, flintpay/flint, or your terminal.
  • Error handling: read a failed response and decide whether to retry.

Was this helpful?