Individual payments

Individual payments can be made if the customer has been registered with a valid payment type. In addition you need to have a default payment acquirer in your Áskell account. Get in touch with us to ensure that you it is all set up before you start.

Like most other actions in the Áskell API this actions requires the Private API key.

Payment status

Individual payments can have, among others, the following statuses.

State identifier

Description

pending

Payment has been established and will be charged immediately

settled

Transaction successful

failed

Transaction unsuccessful and can be retried up to 4 times

retrying

Transaction will be retried as soon as possible

refunded

The payment has been refunded in full

The process

All Swagger API calls in our documentation can be tested and accessible here

  1. A payment has been created for a customer with information on currency and amount. Description and reference from your own CRM or accounting tool is optional.

  • python
API_KEY = 'your api key here'
headers = {
    "Authorization": f"Api-Key {API_KEY}"
}

data = {
    "customer_reference": "customer-12345",
    "amount": "1",
    "currency": "ISK",
    "description": "My description", # Optional description
    "reference": "customer-12345", # Optional reference
}

response = requests.post("https://askell.is/api/payments/", data=data, headers=headers)

The answer looks like this:

{
    "uuid": "a19ca264-5dd4-4897-bcb8-47d84844a2bc",
    "amount": "1.0000",
    "refunded_amount": "0.00",
    "currency": "ISK",
    "description": "My description",
    "reference": "customer-12345",
    "state": "pending",
    "created_at": "2021-10-15T10:02:25.663806Z",
    "updated_at": "2021-10-15T10:02:25.663824Z",
    "transactions": [
        {
        "external_reference": null,
        "data": {},
        "state": "initial",
        "uuid": "951913b0-3b99-4c6c-a58c-3b8e7c18b488",
        "fail_code": null,
        "refund_code": null,
        "cancel_code": null,
        "amount": "1.00",
        "refunded_amount": "0.00",
        "currency": "ISK"
        }
    ]
}
  1. The payment status needs to be monitored through the webhooks. When the payment status changes we send the event payment.changed. Here you can see an example of a payment that has moved through the process and is considered paid.

Further information available through Webhooks

{
    "event": "payment.changed",
    "sender": "admin",
    "data": {
        "uuid": "a19ca264-5dd4-4897-bcb8-47d84844a2bc",
        "amount": "1.0000",
        "refunded_amount": "0.00",
        "currency": "ISK",
        "description": "My description",
        "reference": "customer-12345",
        "state": "settled",
        "created_at": "2021-10-15T10:02:25.663806Z",
        "updated_at": "2021-10-15T10:02:25.663824Z",
        "transactions": [
            {
                "external_reference": "2286047",
                "data": {
                "id": "2286047",
                "receipt": {
                        "BuidAdOgilda": false,
                        "Bunkanumer": "B0003049",
                        "Dagsetning": "14.10.2021",
                        "F22_1til4": "1005",
                        "Faersluhirdir": "VALITOR, sími: 525 2000",
                        "Faerslunumer": "2286047",
                        "FaerslunumerUpphafleguFaerslu": null,
                        "Heimildarnumer": "277031",
                        "Hugbunadarnumer": "11101040000",
                        "Kortnumer": "****-****-****-2779",
                        "LinaC1": "060",
                        "LinaC2": "1509",
                        "LinaC3": "FÆRSLUNR: 128715286045",
                        "LinaC4": "HEIMILD:277031",
                        "LinaD1": "12",
                        "LinaD2": null,
                        "PinSkilabod": null,
                        "PosiID": "0225",
                        "Soluadilinumer": "S0053128",
                        "StadsetningNumer": "0001",
                        "TegundAdgerd": "SALA",
                        "TegundKorts": "Mastercard",
                        "TegundKortsKodi": "500",
                        "TerminalID": "11100126",
                        "Timi": "15:36",
                        "Upphaed": "1",
                        "UtstodNumer": "0001",
                        "VerslunHeimilisfang": null,
                        "VerslunNafn": "Fyrirtækjagreiðslur TEST",
                        "VerslunStadur": "Reykjavík",
                        "Vidskiptaskilabod": "VIÐSKIPTI ISK: 1"
                    },
                    "status": "settled"
                },
                "state": "settled",
                "uuid": "3c03b82a-951a-4331-b651-550de9da9004",
                "fail_code": null,
                "refund_code": null,
                "cancel_code": null,
                "amount": "1.00",
                "refunded_amount": "0.00",
                "currency": "ISK"
            },
        ]
    }
}
  1. There is always a possibility that a payment doesn’t go through for some reason and gets the status failed. In those cases the same payment can be retried with the retry API call. This payment can be retried up to four times.

  • python
API_KEY = 'your api key here'
headers = {
    "Authorization": f"Api-Key {API_KEY}"
}

uuid = "a19ca264-5dd4-4897-bcb8-47d84844a2bc"

response = requests.post(f"https://askell.is/api/payments/{uuid}/retry/", data={}, headers=headers)

Refunding a payment

An individual payment that has been charged can be refunded in full or in part with the following endpoint:

POST /api/payments/{uuid}/refund/

The request requires a private API key or legacy token authentication. A request with a public API key is answered with 403.

The body is optional. With amount, that amount is refunded; without it, everything left to refund is refunded:

{
  "amount": "2500"
}

amount is in the payment’s currency and can be a number or a string. In currencies without decimals, such as ISK, it is a whole number; in other currencies it can have at most two decimal places. It must be more than zero and no more than what is left to refund.

Only a payment in the settled state can be refunded. A payment can be refunded in several parts, up to its amount. A partly refunded payment stays in the settled state, as does its transaction, and refunded_amount on the payment and the transaction shows how much has been refunded. Both move to the refunded state once the whole amount has been refunded.

Partial refunds depend on the payment processor. Teya, Verifone and Straumur accept them; Valitor Pay only from the day after the charge, and only in full for charges from before 2022. Teya RPG only refunds the whole amount. A payment processor that only refunds the whole amount cannot refund what is left of a payment that has already been refunded in part.

  • python
API_KEY = 'your api key here'
headers = {
    "Authorization": f"Api-Key {API_KEY}"
}

uuid = "a19ca264-5dd4-4897-bcb8-47d84844a2bc"

response = requests.post(
    f"https://askell.is/api/payments/{uuid}/refund/",
    json={"amount": "2500"},
    headers=headers,
)

The response is the payment. Here 2,500 ISK of a 7,490 ISK payment has been refunded, so it stays in the settled state (shortened):

{
    "uuid": "a19ca264-5dd4-4897-bcb8-47d84844a2bc",
    "amount": "7490.0000",
    "refunded_amount": "2500.00",
    "currency": "ISK",
    "state": "settled",
    "transactions": [
        {
            "uuid": "3c03b82a-951a-4331-b651-550de9da9004",
            "state": "settled",
            "amount": "7490.00",
            "refunded_amount": "2500.00",
            "currency": "ISK"
        }
    ]
}

HTTP

Description

Next step

200

The refund succeeded. The response is the payment, with refunded_amount on the payment and its transactions. A payment.changed event is sent.

No further action is needed.

202

The payment processor accepted the refund but has not completed it, or its answer did not say how the refund ended (no answer, or a server error). Its amount is held back and is not refunded again in the meantime. The response is the payment, which is still in the settled state.

Do not treat the response as an error and do not immediately resend the request. If the request is sent again without amount while pending refunds hold back everything left to refund, the payment processor is asked about them again under the same keys where it recognises a repeated key (Teya, Verifone). Other payment processors are not asked again, since they could refund twice, and the request is answered with 400 and refund_pending.

400

The refund was refused or the payment processor did not complete it. The response is {"error": ..., "code": ...}, where error is in English. code is one of the codes below.

Act on code rather than on the error text. The payment is unchanged.

403

The request was sent with a public API key.

Use a private API key.

code

Description

transaction_not_refundable

The payment is not in the settled state, for example because it has already been refunded in full, or it has no settled transaction.

refunds_not_supported

The payment’s payment processor does not support refunds, or not for this transaction.

partial_refund_not_supported

The payment processor only refunds the whole amount, or cannot refund part of it yet (Valitor Pay from the day after the charge).

invalid_refund_amount

amount is not a number, not above zero, or has more decimal places than the currency allows.

refund_amount_exceeds_refundable

amount is more than what is left to refund. The error message says how much that is.

refund_failed

The payment processor did not make the refund. The error message says why if the payment processor gave a reason.

refund_pending

Pending refunds hold back everything left, and the payment processor cannot be asked about them again without risking a second refund. Check the refund at the payment processor.

billing_run_charge

uuid is a transaction that a V2 billing run charged, not an individual payment. The response carries the billing run’s billing_run_id; the run is refunded with POST /api/v2/billing-runs/{id}/refund/. See Refunding a billing run.

Charges of legacy subscriptions are refunded the same way; see Refunding a subscription charge.