Reference fields — linking events to payments
Every payment webhook carries three references, and modification events carry a fourth. They look alike but identify different things, and mixing them up is the most common reason an integration cannot match a Capture or Refund event back to the order it belongs to.
The rule that explains most of it: a payfacReference identifies one event, not one payment. The authorization, each capture, each refund and each adjustment are separate events, and each gets its own payfacReference. The event that a modification applies to is named in originalPayfacReference.
The four references
| Field | Created by | Identifies | Where you get it |
|---|---|---|---|
merchantReference | You | Whatever you sent as reference in the request that produced the event — your order number, or a reference you chose for a capture or refund | You already have it. It is echoed back on the event for that request. |
checkoutReference | Straumur | One checkout session (Hosted Checkout, Components) or, for direct Payment Gateway calls and for modifications, one API request | The checkoutReference in the create-checkout or payment response. Not returned for modifications. |
payfacReference | Straumur | One event: one authorization attempt, one capture, one refund, one adjustment | Payment response, Checkout Status when Completed, the Received response of a modification, and every webhook |
originalPayfacReference | Straumur | The authorization a modification applies to | additionalData of Capture, Adjustment and Refund events only |
Two more identifiers you will meet, which are not references to a payment:
responseIdentifieris stamped on every API response. Quote it to support when something goes wrong; it does not appear on webhooks.paymentLinkIdentifierappears on Authorization and Tokenization events for payments made through a payment link and identifies the link, not the payment.
What each event carries
| Event | payfacReference | originalPayfacReference | checkoutReference | merchantReference |
|---|---|---|---|---|
| Authorization | This authorization attempt | — | The checkout session (or the payment request for direct calls) | Your reference from the checkout or payment request |
| Capture | This capture | The authorization | A new reference generated for the capture request | Your reference from the capture request |
| Adjustment | This adjustment | The authorization | A new reference generated for the adjust request | Your reference from the adjust request |
| Refund | This refund, cancel or reversal | The authorization | A new reference generated for the request | Your reference from the request |
| Tokenization | The authorization that created the token | The authorization | The checkout session | Your reference from the checkout |
Things in this table that surprise people:
- The
checkoutReferenceon a Capture, Adjustment or Refund event is not the original checkout's. Each modification request gets a fresh one. To find the payment, useoriginalPayfacReference, or themerchantReferenceyou chose. - Cancel and Reverse are reported as Refund events. There is no separate event type for a cancelled authorization. A
/cancel, a/reverse, and a/refundall arrive aseventType: "Refund"with the authorization inoriginalPayfacReference. - Several Authorization events can share one
checkoutReferencewhen a shopper is declined and retries in the same session. Each attempt has its ownpayfacReference. - Partial captures and partial refunds each produce their own event with their own
payfacReference, all pointing at the sameoriginalPayfacReference.
Worked example
A shopper buys order ORD-1042 for 48 900 kr through Hosted Checkout with manual capture. You capture the full amount, and later refund 10 000 kr.
| Step | You send | You get back | Webhook you receive |
|---|---|---|---|
| 1. Create checkout | reference: "ORD-1042" | checkoutReference: "9eh9g1lo…" | — |
| 2. Shopper pays | — | Checkout Status → Completed, payfacReference: "OOJWITWVQV42PSE8" | Authorization · payfacReference: OOJWITWVQV42PSE8 · checkoutReference: 9eh9g1lo… · merchantReference: ORD-1042 |
| 3. Capture | payfacReference: "OOJWITWVQV42PSE8", reference: "ORD-1042-capture" | status: Received, payfacReference: "3R5TU6ANXRUPA0YP" | Capture · payfacReference: 3R5TU6ANXRUPA0YP · originalPayfacReference: OOJWITWVQV42PSE8 · checkoutReference: (new) · merchantReference: ORD-1042-capture |
| 4. Refund 10 000 kr | payfacReference: "OOJWITWVQV42PSE8", reference: "ORD-1042-refund-1" | status: Received, payfacReference: "MD7XSDUCAA88YCGW" | Refund · payfacReference: MD7XSDUCAA88YCGW · originalPayfacReference: OOJWITWVQV42PSE8 · checkoutReference: (new) · merchantReference: ORD-1042-refund-1 |
Three things to notice:
- Every modification request names the authorization's
payfacReference, even the refund after the capture. You never send a capture's reference anywhere. - The
payfacReferencein a modification'sReceivedresponse is the reference of the new event. The webhook that confirms the outcome carries the same value, so you can store it when you send the request and match the webhook when it arrives. - The only field that ties steps 3 and 4 back to step 2 is
originalPayfacReference.checkoutReferencediffers on every row, andmerchantReferenceis whatever you chose to send.
What to store
- With the order: the
payfacReferenceof the successful Authorization. It is the handle for every later capture, refund, cancel or reverse, and the value you will see asoriginalPayfacReferenceon their events. - With each modification you send: the
payfacReferencefrom theReceivedresponse, so the confirming webhook can be matched even before you look atoriginalPayfacReference. - For deduplication:
payfacReferenceis unique per event. A redelivered webhook (see Delivery and retries) has the samepayfacReferenceas the first delivery. checkoutReference: only needed while a session is open, for the Checkout Status endpoint. Do not use it to link modifications to payments.
reference is required on every modification request. Sending a value that names both the order and the action, such as ORD-1042-refund-1, makes the resulting event self-describing when it arrives in your logs or in the Merchant Portal.
In the Merchant Portal
The portal shows the same events the webhooks do. Under Authorizations, a manually captured payment therefore appears as two rows with two different PSP references: the authorization and the capture. They are the same two events as in steps 2 and 3 above, and the webhook's originalPayfacReference is the link between them.