Agent Wranglers

PAY-71Recommended

Confirm each Swish payment from the callback and a status read

Create each Swish payment request with your own unique ID. Mark the order paid only after the callback or a status read says paid.

How to do it

Swish is the phone payment most Swedes use, in kronor only. You can take it through a payment provider, such as Adyen or Stripe. Or use the Swish API under a merchant agreement with a Swedish bank. The direct API uses a client certificate and lets you choose the payment request ID. A retry with the same ID never creates a second request. It then calls your HTTPS callback address with the result. Treat the callback as a hint. Read the status from Swish before you ship, as Let provider events move the order says for other methods. Norway, Denmark and Finland use Vipps MobilePay instead, offered by the same providers.

Examples

JavaScript example

import { randomUUID } from 'node:crypto'

export async function createSwishRequest(order) {
  const instructionId = order.swishInstructionId ?? randomUUID().replaceAll('-', '').toUpperCase()
  await orders.saveSwishInstructionId(order.id, instructionId)
  await swish.put(`/api/v2/paymentrequests/${instructionId}`, {
    payeeAlias: SWISH_NUMBER,
    amount: (order.totalMinor / 100).toFixed(2),
    currency: 'SEK',
    callbackUrl: 'https://example.com/swish/callback',
    payeePaymentReference: order.id,
  })
  return instructionId
}

Python example

import uuid

def create_swish_request(order) -> str:
    instruction_id = order.swish_instruction_id or uuid.uuid4().hex.upper()
    orders.save_swish_instruction_id(order.id, instruction_id)
    swish.put(
        f"/api/v2/paymentrequests/{instruction_id}",
        json={
            "payeeAlias": SWISH_NUMBER,
            "amount": f"{order.total_minor / 100:.2f}",
            "currency": "SEK",
            "callbackUrl": "https://example.com/swish/callback",
            "payeePaymentReference": order.id,
        },
    )
    return instruction_id

How to check

A test against the Swish test environment creates a payment request twice with the same ID and gets one request. A forged callback that says paid, without a matching status read, leaves the order unpaid.

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/payments/nordic-payments/swish-payments">Agent Wranglers payments and billing playbook</a>. In code you write, add a comment next to it with the same link.