API versionv1 live

Transactions

A transaction is an authorized payment. You capture it to take the money, and refund what you captured. Seq returns it, as a whole object, whenever it changes.

Requests

Request What it does
POST /v1/transactions/{trnid}/capture Capture some or all of what is left of the authorization.
POST /v1/transactions/{trnid}/refund Refund some or all of what was captured.

v1 has no request to void a transaction. A transaction can be voided in the dashboard, and the void then comes through seq as an act; API v2 adds a void request.

A transaction comes into being in one of three ways, and seq returns it in each: a payer pays a payment link, which makes a "transaction"; a payer pays the first charge of a subscriber link as they save their card, which makes a "charge"; or you charge a subscriber, which makes a "charge" and answers with its "id". Either way, its "id" is the {trnid} of the requests above.

The transaction object

Every field below is always there, but where its row says otherwise. A field without a value is an empty string, an empty array, or, for "locked", null; a client must skip fields it doesn't know, as Compatibility says.

Field Type Description
type string "transaction", or "charge" for a charge of a subscriber.
id integer The transaction's ID, the {trnid} of its requests. A shop's transactions are numbered from 1.
rev integer The revision: 1 when the transaction is created, and one higher with each change. Of two copies of a transaction, the one with the higher "rev" is the newer.
locked object or null null, or {"uid": 7812} while we have locked the transaction, where "uid" is the ID of the user who locked it. A locked transaction refuses captures and refunds until it is unlocked.
method.type string How the payer paid: "card", "applepay", or "mobilepay".
method.id string An opaque ID of the card or device, the same for each payment with it in your shop. Use it to recognize a returning card, as for fraud checks; you can't charge it.
method.{type} object The card that paid, named for method.type: method.card for a card, method.applepay for Apple Pay, and method.mobilepay for MobilePay. Look it up by the name in method.type, not as "card", and check that it is there, as a later method may have none.
method.{type}.brand string The card's brand: "visa", "mastercard", "maestro", "dankort", "visadankort", "forbrugsforening", "amex", "diners", "discover", "jcb", or "unionpay", or empty when we don't know it. See the knowledge base's Payment methods.
method.{type}.last4 string The last four digits of the card number.
services array of strings What took part in the payment: "3dsecurev2", "applepay", and "mobilepay", or on older transactions "3dsecure" and "dsbn"; and the acquiring agreement, such as "clearhaus-3" or "nets-1", by the name the dashboard gives it.
info.ip string The IP address, v4 or v6, of the browser that paid.
info.ndisplay integer How many times the payment window was shown before the payment succeeded. Not in a charge.
info.nfail integer How many payments were declined before it. Not in a charge.
time.created integer When the payment link was created, in Unix time: seconds since 1970-01-01 UTC.
time.authorized integer When the payment was authorized, in Unix time.
orderid string Your order ID, from the payment link or the charge.
billing object The billing address, from the payment link or the charge: "name", "company", "vatin", "gln", "email", "phone", "address", an array of lines, "city", "zip", "state", and "country", each as it was given, or empty. See Addresses.
shipping object The shipping address, with the fields of "billing" but "vatin" and "gln".
items array of objects The items, from the payment link or the charge, each with "quantity", "total", "name", and "sku", in the order given. "quantity" is 1 where none was given, and the strings are empty where none was given.
acts array of objects The acts: its captures, refunds, and voids, oldest first.
totals.attempted amount The sum of the items' totals: what the payment asked for.
totals.authorized amount What the issuer authorized. It can be less than "attempted", as a bank may authorize part of a payment, and v1 accepts that: see Partial authorizations.
totals.captured amount The sum of the captures.
totals.refunded amount The sum of the refunds.
totals.voided amount The sum of the voids, or 0.
totals.left amount What can still be captured: authorized - captured - voided, or 0 if that is less than 0.

A transaction that was paid, captured, and partly refunded:

{
    "type": "transaction",
    "id": 378,
    "rev": 3,
    "locked": null,
    "method": {
        "type": "card",
        "id": "WkS3rJht/unginSCpOEwqVtH6SJWt4+StC8TWl+kP6w=",
        "card": {
            "brand": "visadankort",
            "last4": "1234"
        }
    },
    "services": [
        "3dsecurev2",
        "clearhaus-3"
    ],
    "info": {
        "ip": "198.51.100.74",
        "ndisplay": 2,
        "nfail": 0
    },
    "time": {
        "created": 1727088810,
        "authorized": 1727088919
    },
    "orderid": "00029384",
    "billing": {
        "name": "Peter Nielsen",
        "company": "Nielsen A/S",
        "vatin": "DK91738264",
        "gln": "7953878173521",
        "email": "pn@nielsenas.dk",
        "phone": "+45 90014893",
        "address": ["Pederstrupvej 14"],
        "city": "Teststrup",
        "zip": "8320",
        "state": "",
        "country": "DK"
    },
    "shipping": {
        "name": "Peter Nielsen",
        "company": "Nielsen A/S",
        "email": "pn@nielsenas.dk",
        "phone": "+45 90014893",
        "address": ["C/O Peter Nielsen", "Pederstrupvej 14"],
        "city": "Teststrup",
        "zip": "8320",
        "state": "",
        "country": "DK"
    },
    "items": [
        {
            "quantity": 2,
            "total": "199.90 DKK",
            "name": "Danmarkskort plakat",
            "sku": "182932000-MAP-DK"
        },
        {
            "quantity": 1,
            "total": "45 DKK",
            "name": "Fragt - PostNord",
            "sku": ""
        }
    ],
    "acts": [
        {
            "act": "capture",
            "time": 1727109740,
            "uid": null,
            "apikey": "",
            "total": "244.90 DKK",
            "history": []
        },
        {
            "act": "refund",
            "time": 1727196369,
            "uid": 7812,
            "apikey": "",
            "total": "99.95 DKK",
            "history": []
        }
    ],
    "totals": {
        "attempted": "244.90 DKK",
        "authorized": "244.90 DKK",
        "captured": "244.90 DKK",
        "refunded": "99.95 DKK",
        "voided": "0 DKK",
        "left": "0 DKK"
    }
}

Acts

A capture, a refund, or a void is an act. Each one that succeeds is added to "acts", and raises "rev" by one:

Field Type Description
act string "capture", "refund", or "void". A void is made in the dashboard, as v1 has no request for it.
time integer When it was done, in Unix time.
uid integer or null The ID of the user who made the act in the dashboard, or null for an act made with an API key, or by an "autocapture".
apikey string Always "". v1 doesn't record which key made an act.
total amount How much it captured, refunded, or voided.
history array of objects Which items the act covered, each as {"item": 0, "quantity": 1, "total": "99.95 DKK"}, where "item" indexes "items", or []. An "autocapture" records one; an act of yours has [], as v1's requests take no "history". Don't rely on it for amounts: "total" is the truth.

Acts made in the dashboard come through seq like your own, with the user's ID in "uid". So an act with a "uid" is one that you didn't make, and your system should take it as it comes.

Index

The number of acts a transaction has is its index, the length of "acts". A capture or a refund sends it as "index", which you know from the transaction as seq last returned it. If an act has been made since, the index is stale, and the request fails with 500 transaction database error: index mismatch without doing anything. So two requests made from the same state, as by two of your servers, or by you and someone in the dashboard, can't both go through. See Retries and idempotency.

v1 lets you leave "index" out, and then takes it as 0, which is right only for a transaction without acts. Always send it: without it, a second capture fails, and a first one is not checked against what someone else may have done since you last looked.

Rules

  • Capture any amount up to "left", as many times as you like. "left" goes down by each capture.
  • Refund any amount up to captured - refunded, as many times as you like.
  • Void is in the dashboard alone. Once a part is captured, the rest can't be voided, and is released when the authorization runs out.
  • A transaction's amounts are all in its items' currency. Send every act in it.
  • A locked transaction refuses every act until it is unlocked.

v1 doesn't check an act's "total" against "left", what was captured, or the transaction's currency: it sends the act to the acquirer, which refuses what it won't do, with an acquirer error. Check the amount yourself, against the transaction as seq last returned it, before you send it.

Partial authorizations

A bank may authorize less than a payment asked for, as when the card's balance is short. v1 accepts such an authorization, unless the link or charge has "autocapture": the transaction is then for what the bank authorized, "authorized" is less than "attempted", and you can capture no more than "authorized". Compare the two before you deliver an order.

How long an authorization can be captured is not the API's to decide, but the card scheme's and the acquirer's: see the knowledge base's Authorizations.

Charges

A charge of a subscriber is a transaction too, whether you made it with Charge subscriber, or the payer paid it as the first charge of a subscriber link. It differs from a payment link's transaction in this:

  • Its "type" is "charge".
  • Its "info" has only "ip", without "ndisplay" and "nfail".
  • It has a "subscriber": the subscriber it charged, as below.
  • Its "orderid", "items", and addresses come from the request that made it: the charge, or the subscriber link. An address that a charge left out is the subscriber's.
Field Type Description
subscriber.id integer The subscriber's ID.
subscriber.rev integer The subscriber's revision when it was charged.
subscriber.ref string The subscriber's "ref", as you gave it.

Seq returns a charge after its subscriber, as What seq guarantees explains, and you capture and refund it as any transaction.