# Stripe to Anytime Capital: API mapping

> Map Stripe API calls to Anytime Capital: checkout, payment links, customers, prices, subscriptions, invoices, refunds and webhooks, in Node and curl.

Source: https://anytime-capital.com/docs/stripe-api-mapping · Markdown: https://anytime-capital.com/docs/stripe-api-mapping.md · All docs: https://anytime-capital.com/docs/llms-full.txt

If your code calls Stripe today, this page maps each object, call and webhook event a typical integration uses to its Anytime Capital equivalent, with the code side by side, and says plainly what has no equivalent yet. To move your customers, catalog and subscribers across, use the importer in [Switch from Stripe](https://anytime-capital.com/docs/switch-from-stripe.md).

## At a glance

|  | Stripe | Anytime Capital |
| --- | --- | --- |
| Base URL | `https://api.stripe.com/v1` | `https://anytime-capital.com/api/v1` |
| Keys | `sk_live_` secret, `rk_live_` restricted, `pk_live_` publishable | `ak_live_` secret keys, each restrictable per resource. No publishable key: card details are only ever typed into our hosted or embedded checkout. See [Authentication](https://anytime-capital.com/docs/authentication.md). |
| Test mode | `sk_test_` keys | `ak_test_` keys from test mode in the dashboard; objects and events carry `livemode: false`. See [Test mode](https://anytime-capital.com/docs/test-mode.md). |
| Request bodies | Form-encoded | JSON |
| Amounts | `amount` in the smallest unit | Integer cents, named for what they are: `amountCents`, `priceCents`, `unitCents` |
| Currency | Many | US dollars (`currency: "usd"`). See [International customers](https://anytime-capital.com/docs/international-customers.md). |
| Pagination | `limit` with `starting_after`; `has_more` | `limit` (up to 100) with `cursor` set to the last page's `nextCursor`; `hasMore`. Newest first. See [Pagination](https://anytime-capital.com/docs/pagination.md). |
| Idempotency | `Idempotency-Key` header | The same header on every write, remembered 24 hours; a replay answers with `Idempotent-Replayed: true`. See [Idempotency](https://anytime-capital.com/docs/idempotency.md). |
| Errors | `error.type`, `error.code`, `error.message`, `error.param` | `error.code` and `error.message` (it names the field). See [Error codes](https://anytime-capital.com/docs/error-codes.md). |
| Request ids | `Request-Id` header | `Request-Id` header (`req_…`), also in the request log in **Settings → Developers** |
| Metadata | On most objects | On payment links, copied onto each payment made on them. Customers have `notes`. |
| Libraries | `stripe` for Node and others | `fetch` (every reference page has the Node.js version), a [Node SDK](https://anytime-capital.com/docs/node-sdk.md) preview, or a client generated from the [OpenAPI document](https://anytime-capital.com/docs/openapi.md) |

## Objects and calls

| Stripe | Anytime Capital | Notes |
| --- | --- | --- |
| `checkout.sessions.create` (payment) | `POST /payment-links` with `singleUse: true` | Redirect to the link's `url`. `success_url` → `successUrl`, `metadata` → `metadata`, `allow_promotion_codes` → `allowDiscountCodes`, `shipping_address_collection` → `collectShipping`, `customer_email` → `?prefilled_email=` on the url, `client_reference_id` → `?ref=` on the url (stored as the payment's `clientReference`). |
| `checkout.sessions.create` (subscription) | The subscription plan's `url` | Send customers to `url` from `POST /subscription-plans` or `GET /subscription-plans/{id}`. |
| `paymentLinks.create` / `update` | `POST /payment-links` / `POST /payment-links/{id}` | A price in `amountCents` (no Price object). The price can't change after creation: create a new link. |
| `paymentLinks.update({ active: false })` | `POST /payment-links/{id}/deactivate` | There's no API to turn a link back on. |
| `paymentIntents.retrieve` / `list` | `GET /payments/{id}` / `GET /payments` | `status: "paid"` for succeeded. `amountCents`, `amountRefundedCents`, `netCents`, `metadata`, `clientReference`, `customer`. |
| `customers.create` / `update` / `retrieve` | `POST /customers` / `PATCH /customers/{id}` / `GET /customers/{id}` | One customer per email address; card buyers are added on their own when they first pay. |
| `customers.list({ email })` | `GET /customers?email=` | Filter by email only; there's no search query language. |
| `products.create` + `prices.create` (one-time) | `POST /products` with `priceCents` | A product has one price. `products.update` → `PATCH /products/{id}`; `active: false` → `POST /products/{id}/archive`. |
| `prices.create` (recurring) | `POST /subscription-plans` | `interval`: `week`, `month`, `quarter`, `year`; `trialDays` up to 90. |
| `subscriptions.list` / `retrieve` | `GET /subscriptions` / `GET /subscriptions/{id}` | Filter by `status`, `planId` or `customerEmail`. |
| `subscriptions.update({ cancel_at_period_end: true })` / `subscriptions.cancel` | `POST /subscriptions/{id}/cancel` with `atPeriodEnd` `true` / `false` | The subscriber gets the same email as when you cancel in the dashboard. |
| `subscriptions.update({ pause_collection })` / resume | `POST /subscriptions/{id}/pause` / `POST /subscriptions/{id}/resume` |  |
| `invoices.create` + `invoiceItems.create` + `finalizeInvoice` + `sendInvoice` | `POST /invoices` | One call with `customerName`, `customerEmail`, `lineItems`, `dueDate` and optional `taxBps`, `discountCents`, `deposit`. Emailed at once unless `send: false`; `POST /invoices/{id}/send` sends it, or a reminder after that. |
| `refunds.create` | `POST /refunds` | `payment_intent` → `paymentId`, `amount` → `amountCents`. Over your refund approval limit it answers `202` with `status: "pending_approval"` until an owner approves. |
| `coupons.create` + `promotionCodes.create` | `POST /discount-codes` | `percentOffBps` (1500 is 15%) or `amountOffCents`, `maxRedemptions`, `expiresAt`. Deactivate with `POST /discount-codes/{id}/deactivate`. |
| `disputes.list` / `retrieve` | `GET /disputes` / `GET /disputes/{id}` | Read only, with the automatic evidence pack. Respond in the dashboard. |
| `payouts.list` / `balance.retrieve` | `GET /payouts` / `GET /balance` | Read only. Payouts go to your bank account on your schedule. |
| `webhookEndpoints.create` | `POST /webhook-endpoints` | `enabled_events` → `events` (or `["*"]`). The response carries the signing `secret` once. |
| `events.list` / `retrieve` | `GET /events` / `GET /events/{id}` | The last 30 days. `type` takes an event type, a family such as `payment.*`, or up to 10 of them; `createdFrom` and `createdTo` take ISO 8601 dates. |
| `billing.meterEvents.create` | `POST /meter-events` | `event_name` → `eventName`, `payload.value` → `value`, with a required `idempotencyKey` per event. See [Meters](https://anytime-capital.com/docs/meters.md). |

## Accept a payment

A Checkout Session becomes a single-use payment link: create it from your server with the order in `metadata`, redirect the customer to its `url`, and fulfil the order on the `payment.succeeded` webhook, where `data.metadata.orderId` comes back. There is no PaymentIntent to create or confirm yourself.

**Stripe (Node)**

```javascript
import Stripe from "stripe";

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);

const session = await stripe.checkout.sessions.create(
  {
    mode: "payment",
    line_items: [
      { price_data: { currency: "usd", unit_amount: 12500, product_data: { name: "Order #1042" } }, quantity: 1 },
    ],
    success_url: "https://example.com/thanks",
    metadata: { orderId: "1042" },
  },
  { idempotencyKey: "order-1042-checkout" },
);
res.redirect(303, session.url);
```

**Anytime Capital (Node)**

```javascript
// One single-use payment link per order: its url is the hosted checkout.
const response = await fetch("https://anytime-capital.com/api/v1/payment-links", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.ANYTIME_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": "order-1042-link",
  },
  body: JSON.stringify({
    title: "Order #1042",
    amountCents: 12500,
    singleUse: true,
    successUrl: "https://example.com/thanks",
    metadata: { orderId: "1042" },
  }),
});
const link = await response.json();
if (!response.ok) throw new Error(`${link.error.code}: ${link.error.message}`);
res.redirect(303, link.url);
```

**Stripe (curl)**

```bash
curl https://api.stripe.com/v1/checkout/sessions \
  -u "$STRIPE_SECRET_KEY:" \
  -H "Idempotency-Key: order-1042-checkout" \
  -d mode=payment \
  -d "line_items[0][price_data][currency]=usd" \
  -d "line_items[0][price_data][unit_amount]=12500" \
  -d "line_items[0][price_data][product_data][name]=Order #1042" \
  -d "line_items[0][quantity]=1" \
  -d success_url="https://example.com/thanks" \
  -d "metadata[orderId]=1042"
```

**Anytime Capital (curl)**

```bash
curl https://anytime-capital.com/api/v1/payment-links \
  -H "Authorization: Bearer $ANYTIME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1042-link" \
  -d '{"title":"Order #1042","amountCents":12500,"singleUse":true,"successUrl":"https://example.com/thanks","metadata":{"orderId":"1042"}}'
```

Line items with catalog products can't be sent through the API yet: send the order's total as `amountCents` and describe it in `title` and `description`. Links you build from products in the dashboard list their `items`. For a checkout on your own page rather than a redirect, put the same link in the [inline checkout](https://anytime-capital.com/docs/checkout.md#inline-checkout).

## Read a payment

**Stripe (Node)**

```javascript
const intent = await stripe.paymentIntents.retrieve("pi_3Q…");
if (intent.status === "succeeded") {
  console.log(intent.amount_received, intent.metadata.orderId);
}
```

**Anytime Capital (Node)**

```javascript
const response = await fetch("https://anytime-capital.com/api/v1/payments/pay_7Hq2LmX9cR4tVb", {
  headers: { Authorization: `Bearer ${process.env.ANYTIME_API_KEY}` },
});
const payment = await response.json();
if (payment.status === "paid") {
  // netCents is what you keep after fees; metadata came from the payment link.
  console.log(payment.amountCents, payment.netCents, payment.metadata.orderId);
}
```

**Stripe (curl)**

```bash
curl https://api.stripe.com/v1/payment_intents/pi_3Q… -u "$STRIPE_SECRET_KEY:"
```

**Anytime Capital (curl)**

```bash
curl https://anytime-capital.com/api/v1/payments/pay_7Hq2LmX9cR4tVb \
  -H "Authorization: Bearer $ANYTIME_API_KEY"
```

## Customers

**Stripe (Node)**

```javascript
const [existing] = (await stripe.customers.list({ email: "jordan@example.com", limit: 1 })).data;
const customer =
  existing ?? (await stripe.customers.create({ name: "Jordan Lee", email: "jordan@example.com", phone: "+1 555 0100" }));
```

**Anytime Capital (Node)**

```javascript
const headers = {
  Authorization: `Bearer ${process.env.ANYTIME_API_KEY}`,
  "Content-Type": "application/json",
};
// One customer per email address: look before you create.
const found = await fetch("https://anytime-capital.com/api/v1/customers?email=jordan%40example.com", { headers }).then((r) => r.json());
const customer =
  found.data[0] ??
  (await fetch("https://anytime-capital.com/api/v1/customers", {
    method: "POST",
    headers: { ...headers, "Idempotency-Key": "customer-jordan" },
    body: JSON.stringify({ name: "Jordan Lee", email: "jordan@example.com", phone: "+1 555 0100" }),
  }).then((r) => r.json()));
```

**Stripe (curl)**

```bash
curl https://api.stripe.com/v1/customers \
  -u "$STRIPE_SECRET_KEY:" \
  -d name="Jordan Lee" -d email=jordan@example.com
```

**Anytime Capital (curl)**

```bash
curl https://anytime-capital.com/api/v1/customers \
  -H "Authorization: Bearer $ANYTIME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: customer-jordan" \
  -d '{"name":"Jordan Lee","email":"jordan@example.com"}'
```

## Products, prices and plans

There's no separate Price object. A product carries its one price in `priceCents`; a recurring price is a subscription plan, which has its own checkout `url`.

**Stripe (Node)**

```javascript
const mug = await stripe.products.create({ name: "Ceramic mug" });
await stripe.prices.create({ product: mug.id, unit_amount: 1800, currency: "usd" });

const membership = await stripe.products.create({ name: "Studio membership" });
await stripe.prices.create({
  product: membership.id,
  unit_amount: 4900,
  currency: "usd",
  recurring: { interval: "month", trial_period_days: 14 },
});
```

**Anytime Capital (Node)**

```javascript
const post = (path, body, key) =>
  fetch(`https://anytime-capital.com/api/v1${path}`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.ANYTIME_API_KEY}`,
      "Content-Type": "application/json",
      "Idempotency-Key": key,
    },
    body: JSON.stringify(body),
  }).then((r) => r.json());

// A product carries its one price.
const mug = await post("/products", { name: "Ceramic mug", priceCents: 1800 }, "product-mug");

// A recurring price is a subscription plan; customers subscribe on its url.
const plan = await post(
  "/subscription-plans",
  { title: "Studio membership", amountCents: 4900, interval: "month", trialDays: 14 },
  "plan-studio-monthly",
);
console.log(plan.url);
```

**Anytime Capital (curl)**

```bash
curl https://anytime-capital.com/api/v1/products \
  -H "Authorization: Bearer $ANYTIME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: product-mug" \
  -d '{"name":"Ceramic mug","priceCents":1800}'

curl https://anytime-capital.com/api/v1/subscription-plans \
  -H "Authorization: Bearer $ANYTIME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: plan-studio-monthly" \
  -d '{"title":"Studio membership","amountCents":4900,"interval":"month","trialDays":14}'
```

## Cancel a subscription

**Stripe (Node)**

```javascript
// At the end of the period…
await stripe.subscriptions.update("sub_1Q…", { cancel_at_period_end: true });
// …or now.
await stripe.subscriptions.cancel("sub_1Q…");
```

**Anytime Capital (Node)**

```javascript
const cancel = (atPeriodEnd) =>
  fetch("https://anytime-capital.com/api/v1/subscriptions/sub_2208/cancel", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.ANYTIME_API_KEY}`,
      "Content-Type": "application/json",
      "Idempotency-Key": `cancel-sub_2208-${atPeriodEnd}`,
    },
    body: JSON.stringify({ atPeriodEnd }),
  }).then((r) => r.json());

await cancel(true); // cancelAtPeriodEnd is true until the period ends
// await cancel(false); // ends it now
```

**Anytime Capital (curl)**

```bash
curl https://anytime-capital.com/api/v1/subscriptions/sub_2208/cancel \
  -H "Authorization: Bearer $ANYTIME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: cancel-sub_2208" \
  -d '{"atPeriodEnd":true}'
```

## Invoices

**Stripe (Node)**

```javascript
const invoice = await stripe.invoices.create({ customer: "cus_Q…", collection_method: "send_invoice", days_until_due: 30 });
await stripe.invoiceItems.create({ customer: "cus_Q…", invoice: invoice.id, amount: 450000, currency: "usd", description: "Website redesign" });
await stripe.invoices.finalizeInvoice(invoice.id);
await stripe.invoices.sendInvoice(invoice.id);
```

**Anytime Capital (Node)**

```javascript
// One call: created, totalled and emailed (send: false to send it later).
const response = await fetch("https://anytime-capital.com/api/v1/invoices", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.ANYTIME_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": "invoice-northwind-oct",
  },
  body: JSON.stringify({
    customerName: "Northwind LLC",
    customerEmail: "ap@northwind.example",
    lineItems: [{ description: "Website redesign", quantity: 1, unitCents: 450000 }],
    taxBps: 825,
    dueDate: "2026-11-15",
  }),
});
const invoice = await response.json(); // invoice.url is its pay page
```

**Anytime Capital (curl)**

```bash
curl https://anytime-capital.com/api/v1/invoices \
  -H "Authorization: Bearer $ANYTIME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: invoice-northwind-oct" \
  -d '{"customerName":"Northwind LLC","customerEmail":"ap@northwind.example","lineItems":[{"description":"Website redesign","quantity":1,"unitCents":450000}],"taxBps":825,"dueDate":"2026-11-15"}'
```

## Refunds

**Stripe (Node)**

```javascript
await stripe.refunds.create(
  { payment_intent: "pi_3Q…", amount: 2500, reason: "requested_by_customer" },
  { idempotencyKey: "refund-order-1042" },
);
```

**Anytime Capital (Node)**

```javascript
const response = await fetch("https://anytime-capital.com/api/v1/refunds", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.ANYTIME_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": "refund-order-1042",
  },
  body: JSON.stringify({ paymentId: "pay_7Hq2LmX9cR4tVb", amountCents: 2500, reason: "requested_by_customer" }),
});
const refund = await response.json();
// 201: refunded. 202: over your approval limit, waiting for an owner (status "pending_approval").
```

**Stripe (curl)**

```bash
curl https://api.stripe.com/v1/refunds \
  -u "$STRIPE_SECRET_KEY:" \
  -H "Idempotency-Key: refund-order-1042" \
  -d payment_intent=pi_3Q… -d amount=2500 -d reason=requested_by_customer
```

**Anytime Capital (curl)**

```bash
curl https://anytime-capital.com/api/v1/refunds \
  -H "Authorization: Bearer $ANYTIME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: refund-order-1042" \
  -d '{"paymentId":"pay_7Hq2LmX9cR4tVb","amountCents":2500,"reason":"requested_by_customer"}'
```

## Webhooks

Signatures work the same way: `Anytime-Signature` is `t=<unix seconds>,v1=<hex>`, an HMAC-SHA256 of `<t>.<raw body>` keyed with your endpoint's `whsec_…` secret. Three things differ in the event itself: `data` is the object (not `data.object`), `created` is an ISO 8601 string (not Unix seconds), and there's no `previous_attributes`, so re-read the object from the API when you need what changed.

**Stripe (Node, Express)**

```javascript
app.post("/webhooks", express.raw({ type: "application/json" }), (req, res) => {
  const event = stripe.webhooks.constructEvent(req.body, req.get("Stripe-Signature"), process.env.STRIPE_WEBHOOK_SECRET);
  if (event.type === "checkout.session.completed") {
    fulfil(event.data.object.metadata.orderId);
  }
  res.sendStatus(200);
});
```

**Anytime Capital (Node, Express)**

```javascript
import crypto from "node:crypto";

// Anytime-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">
function verifyEvent(rawBody, header, secret) {
  const pairs = header.split(",").map((part) => part.trim().split("="));
  const t = pairs.find(([key]) => key === "t")?.[1] ?? "";
  const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
  const signed = pairs.some(
    ([key, value = ""]) =>
      key === "v1" && value.length === expected.length && crypto.timingSafeEqual(Buffer.from(value), Buffer.from(expected)),
  );
  if (!signed || Math.abs(Date.now() / 1000 - Number(t)) > 300) throw new Error("Invalid signature");
  return JSON.parse(rawBody);
}

app.post("/webhooks", express.raw({ type: "application/json" }), (req, res) => {
  let event;
  try {
    event = verifyEvent(req.body.toString("utf8"), req.get("Anytime-Signature") ?? "", process.env.ANYTIME_WEBHOOK_SECRET);
  } catch {
    return res.sendStatus(400);
  }
  if (event.type === "payment.succeeded") {
    fulfil(event.data.metadata.orderId); // event.data is the payment itself
  }
  res.sendStatus(200);
});
```

The [Node SDK](https://anytime-capital.com/docs/node-sdk.md) preview has the same `constructEvent(rawBody, header, secret)`. Endpoints must be public `https://` URLs: add them in **Settings → Developers** or with `POST /webhook-endpoints`. See [Verify webhook signatures](https://anytime-capital.com/docs/webhook-signatures.md) for Next.js, Python and PHP.

## Webhook events

| Stripe event | Anytime Capital event | `data` is |
| --- | --- | --- |
| `checkout.session.completed`, `payment_intent.succeeded`, `charge.succeeded` | `payment.succeeded` | the payment |
| `payment_intent.payment_failed`, `charge.failed` | `payment.failed` | the payment |
| `charge.refunded` | `payment.refunded` | the payment |
| `refund.created` | `refund.created` | the refund |
| `refund.updated` (succeeded / failed) | `refund.succeeded` / `refund.failed` | the refund |
| `charge.dispute.created` | `dispute.opened` | the payment |
| `charge.dispute.updated` | `dispute.updated` | the dispute |
| `charge.dispute.closed` | `dispute.closed` | the payment |
| `invoice.created`, `invoice.finalized` | `invoice.created` | the invoice |
| `invoice.sent` | `invoice.sent` | the invoice |
| `invoice.paid` | `invoice.paid` | the invoice |
| `invoice.overdue` | `invoice.overdue` | the invoice |
| `invoice.voided` | `invoice.voided` | the invoice |
| `customer.subscription.created` | `subscription.created` | the subscription |
| `customer.subscription.updated` | `subscription.updated` | the subscription |
| `customer.subscription.paused` / `resumed` | `subscription.paused` / `subscription.resumed` | the subscription |
| `invoice.payment_failed` on a renewal | `subscription.past_due` | the subscription |
| `customer.subscription.deleted` | `subscription.canceled` | the subscription |
| `customer.created` / `customer.updated` | `customer.created` / `customer.updated` | the customer |
| `payout.paid` / `payout.failed` | `payout.paid` / `payout.failed` | the payout |
| `review.opened` | `payment.review_required` | the payment |

Events with no counterpart here include `checkout.session.expired`, `payment_intent.created`, `payment_intent.processing`, `payment_intent.requires_action`, `setup_intent.*`, `payment_method.*`, `customer.deleted`, `product.*`, `price.*`, `invoice.upcoming` and `customer.subscription.trial_will_end`. See [Webhooks](https://anytime-capital.com/docs/webhooks.md#event-types) for every event type.

## Catch up on events

**Stripe (Node)**

```javascript
for await (const event of stripe.events.list({ type: "payment_intent.succeeded", created: { gte: 1760400000 } })) {
  handle(event);
}
```

**Anytime Capital (Node)**

```javascript
// Newest first; follow nextCursor until hasMore is false.
let cursor;
do {
  const url = new URL("https://anytime-capital.com/api/v1/events");
  url.searchParams.set("type", "payment.*");
  url.searchParams.set("createdFrom", "2026-10-14T00:00:00Z");
  url.searchParams.set("limit", "100");
  if (cursor) url.searchParams.set("cursor", cursor);
  const page = await fetch(url, { headers: { Authorization: `Bearer ${process.env.ANYTIME_API_KEY}` } }).then((r) => r.json());
  for (const event of page.data) handle(event);
  cursor = page.hasMore ? page.nextCursor : undefined;
} while (cursor);
```

**Anytime Capital (curl)**

```bash
curl "https://anytime-capital.com/api/v1/events?type=payment.*&createdFrom=2026-10-14&limit=100" \
  -H "Authorization: Bearer $ANYTIME_API_KEY"
```

## Test locally

The [Anytime CLI](https://anytime-capital.com/docs/cli.md) (in preview, not on npm yet) does what the Stripe CLI's `listen` and `trigger` do: it forwards your test events to localhost, signed with a local secret in the same header format, and sends test events through the [test helpers](https://anytime-capital.com/docs/test-helpers.md).

```bash
# Before
stripe listen --forward-to localhost:3000/webhooks
stripe trigger payment_intent.succeeded

# After (the Anytime CLI, in preview)
anytime listen --forward-to localhost:3000/webhooks
anytime trigger payment.succeeded
```

## No equivalent yet

- **Collecting or charging a card through the API.** There are no PaymentIntents, SetupIntents, PaymentMethods or Elements: cards are entered only in our hosted or embedded checkout, and there's no call to charge a saved card off session.
- **Separate authorization and capture.** There's no `capture_method: manual`; payments our risk rules hold are approved in the dashboard (`payment.review_required`).
- **Creating or changing subscriptions from your server.** Customers subscribe on a plan's `url`. Plan changes with proration, coupons on subscriptions and several items per subscription are dashboard features; there are no subscription schedules or test clocks.
- **Currencies other than US dollars**, and automatic tax calculation: set `taxBps` on invoices yourself.
- **Metadata beyond payment links and payments**, `expand[]`, search queries, and API version headers: objects carry what they need, and the [Changelog](https://anytime-capital.com/docs/changelog.md) and the OpenAPI document's version track changes.
- **Deleting customers or products, voiding invoices and answering disputes through the API.** Do these in the dashboard; products are archived instead of deleted.
- **Creating payouts through the API, connected accounts and card issuing.** Payouts and the balance can be read: `GET /payouts`, `GET /balance`.
- **Expiring a checkout.** Deactivate the link instead: `POST /payment-links/{id}/deactivate`.
- **Fraud rules through the API.** They're set in the dashboard: see [Fraud rules & 3D Secure](https://anytime-capital.com/docs/risk-and-3ds.md).

- [Switch from Stripe](https://anytime-capital.com/docs/switch-from-stripe.md): Import customers, catalog, codes and open invoices, then move subscribers.
- [Postman collection](https://anytime-capital.com/docs/postman.md): Every endpoint, ready to send with a test key.
- [Next.js checkout](https://anytime-capital.com/docs/nextjs-checkout.md): A complete payment-link checkout and webhook in an App Router app.

---

Anytime Capital is a fintech company, not a bank. Payment processing, banking and payout services are provided by Anytime Capital's licensed partners. Rates shown are for US card payments; international cards, currency conversion and disputes may carry additional fees shown in your dashboard before you accept a payment.
