NAV Navbar

Introduction

viafintech API v2 allows you to create payment, partial payment, payout, and refund slips customers can use in stores like supermarkets to pay or receive money. Slips are sent to users as an email with a PDF attachment or as a text message. When a store's point of sale system confirms the transaction, viafintech usually immediately calls a Webhook to notify your system about the payment. You can then use this confirmation e.g. to mark an invoice as paid or trigger shipping goods to the customer.

The name viafintech refers to the company viafintech GmbH. The names Barzahlen and viacash refer to the same product. For the remainder of the document we will refer to it as viacash.

The API is a JSON-based REST API.

We provide client libraries for the following programming languages:

Functionality

Slip Types

If you have any problems with your integration, regarding any of the slip types, please contact us.

Slip States

A slip is in one of four states, all except pending are final.

Identifying a customer

To reduce money laundering, we are required to store an identifier that is unique per customer. Depending on your contract with viafintech, this can be an email address or an internal customer identifier. You must provide the identifier in the customer key field. If you provide an email address as customer key, you must use the same email address in the email field.

Accessing the API

The API is accessible via HTTPS and uses JSON as format for requests and responses. As REST-API, it uses different HTTP methods to indicate the type of request and response codes for indicating the outcome of a request. For errors, it returns additional, more specific error classes, codes, and messages.

The API endpoints are:

HTTPS/TLS Protocols and Certificates

We employ TLS protocols to ensure secure communications between our systems and our partners' systems. Our systems currently supports both TLS 1.2 and TLS 1.3, using a range of secure encryption ciphers. We expect our partners to implement support for these protocols in their systems as well, to guarantee secure data transmission.

Additionally, we require our partners to maintain an up-to-date list of trusted root certificates (CA Root certificates). This ensures that new HTTPS/TLS connections can be properly verified and trusted, mitigating the risk of man-in-the-middle attacks. We strongly recommend always verifying HTTPS server certificates against trusted root certificates. This includes validating the certificate chain and verifying the server name(s) against the certificate. Refer to your HTTP client’s documentation for details on performing these and other required checks.

To facilitate secure integration, we provide a curated bundle of root certificates (download below) from reputable Certificate Authorities (CAs) that we currently or may in the future use for obtaining certificates for this API. Feel free to integrate this list into your systems to establish secure and reliable connections to our API services or you can also rely on your already existing system trust store. By using either this tailored certificate bundle or your system trust store, you can ensure a seamless and secure experience while making the renewal of our certificates effortless on your end.

Sandbox

Sandbox mode allows working on slips that can not actually be paid in a store. Instead, you can use the viafintech App to simulate payment and expiry and receive webhooks for these events. Text messages are not sent in sandbox mode, but emails are.

In contrast to the production endpoint, the sandbox endpoint is available immediately after you sign up, so you can begin integrating viacash as soon as possible.

Optional Features

Authentication

For authentication, the API requires requests to be signed using your API key. You will never have to include your API key in plain text in a request, only as part of the signature. We use the same signature algorithm to sign webhook requests to your system.

For authentication and webhook signature verification, you will need your division id and your API key. You can find both in the viafintech App under Settings / Divisions.

See Accessing the API for information about HTTPS certificate verification.

API Requests

Authorization header format for API requests

Authorization: BZ1-HMAC-SHA256 DivisionId=ID, Signature=SIGNATURE

For requests, the API expects a standard HTTP Authorization header with a custom authentication scheme, BZ1-HMAC-SHA256.

Replace ID with your division's ID and SIGNATURE with a signature based on certain parts of the request. The algorithm for calculating the signature is described below.

Example Date header

Date: Tue, 15 Nov 1994 08:12:31 GMT

The signature includes the current time, which must be included in the request's Date header.

When the Authorization header is missing or invalid, the API returns HTTP status 401 with an WWW-Authenticate: BZ1-HMAC-SHA256 header and an error.

Webhook Requests

For webhooks, we provide the signature in a custom header, Bz-Signature.

Bz-Signature header format for webhook requests

Bz-Signature: BZ1-HMAC-SHA256 SIGNATURE

SIGNATURE will be replaced with a signature based on certain parts of the request. The algorithm for calculating the signature is described below. Webhook requests contain a Date header as used in API requests.

When receiving webhooks, always verify the signature.

Calculating the Signature

Calculating the signature means generating a string with certain parameters and then using your division's API key to sign the string with HMAC-SHA256. This section describes the signature process and the next section contains a signature generator you can use to verify and debug your implementation.

The string to sign contains parameters in the following order, separated by newlines (line feed characters only).

Example String to sign

api.viafintech.com:443
GET
/v2/slips/slp-d90ab05c-69f2-4e87-9972-97b3275a0ccd

Thu, 31 Mar 2016 10:50:31 GMT

e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

The newlines are always necessary, regardless whether a value is empty or not, so the number of lines in the string to sign is always the same. Do not add a newline after the body digest. Make sure to only use the line feed characters, and no carriage returns.

When a value is empty (e.g. an empty query string), you will still have to add the newline.

The last step is signing the string with your API key. Use the API key in the form we provide it (do not convert the data to binary, even if it is in hexidecimal form).

Example Key: 6b3fb3abef828c7d10b5a905a49c988105621395

Ruby Example showing HMAC-SHA256 signing

require 'openssl'
signature = OpenSSL::HMAC.hexdigest('sha256', payment_key, string_to_sign)

Use the the API key to sign the string using HMAC with SHA-256 as hash function and encode the resulting bytes in hexidecimal form.

With the example string and example key above, you can calculate the following signature:

Example Signature: 3ebd7a069c0c0f6aafd537866c2b3af6594878eb62db51e2350bfba396971745

Example Request

Example Request with signature in Authorization header

GET /v2/slips/slp-d90ab05c-69f2-4e87-9972-97b3275a0ccd HTTP/1.1
Authorization: BZ1-HMAC-SHA256 DivisionId=20065, Signature=3b1a28fffd1cd2bbc1ec24cfbca1e85d802159e78c08328d92d4337a4a33b61d
Date: Thu, 31 Mar 2016 10:50:31 GMT
Host: api.viafintech.com

The example shows an API request including all headers required for authentication.

You can find an example for webhooks in the Webhooks section.

Signature Generator

This signature generator allows you to verify and debug your implementation of API v2's signature algorithm.

Note:

The bytes put into the signature must be the same sent with the actual request, so different kinds of newlines and whitespace can invalidate the signature.

Signature

String to Sign









Idempotency

Most methods on resources in viafintech API v2 can or even must be used in an idempotent way, so you can automatically retry requests without having unintended side effects.

Retrying requests makes your system more resilient when network failures happen, our system temporarily fails to process your request or your division exceeds the rate limit. We highly recommend implementing automated retries - they are necessary for reliable use of any network-based API.

Here is an overview of the idempotency properties of the different methods and resources:

Using the Idempotency-Key header in any endpoint other than POST /slips has no effect and will be ignored.

Rate Limiting

Request Limit

The API is rate limited per division to ensure that no single division can use too much server resources.

Example API response headers after a single request

HTTP/1.1 200 OK
Content-Length: 363
Content-Type: application/json;charset=utf-8
Date: Tue, 03 May 2016 10:54:54 GMT
Ratelimit-Limit: 31
Ratelimit-Remaining: 30
Ratelimit-Reset-After: 1
Request-Id: 2b48b13ec1994d1e9cc577058c7b3be1

If the limit is reached, additional requests are not processed and a rate_limit_exceeded error is returned with HTTP status code 429. Over time, requests will be allowed again (as indicated by the Retry-After header) and the request can be repeated.

The API uses a 'leaky bucket' algorithm for rate limiting. It allows a sustained rate of 1 request per second, i.e. the bucket 'leaks' one request per second. The bucket has a size of 31, so a divison can execute a burst of 31 requests at once (within one second) before the limit is reached, i.e. the bucket is full. The next request is available after a second, when one request has 'leaked' from the bucket. Each second, another request 'leaks' from the bucket until after 31 seconds without requests, the bucket is empty again.

If you expect to reach these limits, you should implement client-side rate limit to prevent getting rate_limit_exceeded errors. When getting such an error, do not immediately retry a request, but wait at least the time indicated by the Retry-After header.

The following rate limiting-related headers are returned:

Transaction Limit

There is also a per-division transaction creation rate limit. It's set pretty high, so most divisions are unlikely to be affected by it. If you plan on creating more than 10000 slips per 24 hours, please contact us.

In contrast to the request rate limit, the API does not return additional information about the state of the transaction limit as we expect divisions to not reach the limit under normal circumstances. When a division hits the limit nevertheless, the API returns the transaction_creation_rate_limit_exceeded error. In that case, please contact us.

Webhooks

Example Webhook Request

POST /viacash/callback HTTP/1.1
Host: callback.example.com
Date: Fri, 01 Apr 2016 09:20:06 GMT
Bz-Hook-Format: v2
Bz-Signature: BZ1-HMAC-SHA256 6519d1b3f85a7879fe5d2915bab4d0392976ea63ce6ef50b9006c693a029d3e0
Content-Type: application/json;charset=utf-8
Content-Length: 414
User-Agent: viacash Notifier

{
    "event": "paid",
    "event_occurred_at": "2016-01-06T12:34:56Z",
    "affected_transaction_id": "4729294329",
    "slip": {
        "id": "slp-d90ab05c-69f2-4e87-9972-97b3275a0ccd",
        "slip_type": "payment",
        "division_id": "1234",
        "reference_key": "O64737X",
        "hook_url": null,
        "expires_at": "2016-01-10T12:34:56Z",
        "customer": {
            "key": "LDFKHSLFDHFL",
            "cell_phone_last_4_digits": "6789",
            "email": "john@example.com",
            "language": "de-DE"
        },
        "metadata": {
          "order_id": "1234",
          "invoice_no": "A123"
        },
        "transactions": [
            {
                "id": "4729294329",
                "currency": "EUR",
                "amount": "123.34",
                "state": "paid",
                "displayed_due_at": "2016-01-10T10:00:00Z"
            }
        ],
        "nearest_stores": []
    }
}

When a relevant event occurred for a slip or transaction, our system does an HTTPS-request on a URL you can specify. These relevant events occur when transactions expire, are canceled, declined, paid, or when the pay confirmation was received from the retailer or the retailer canceled the confirmation during the cooldown period. You can set the URL up in the viafintech App under Settings / Divisions / Notification URL. Alternatively, if you want to use different hook URLs for some of the transactions, you can specify a hook_url when creating a transaction.

A webhook request is done as POST request with a JSON body. The body contains the event that happened (paid, expired, canceled, declined, locked, unlocked, money_received, money_returned), a timestamp when the event occurred and the id of the transaction affected by the event. The body also contains a complete slip resource, so you can access a given reference_key or metadata. When executing webhooks, we do not follow redirects.

Webhook requests are signed in the same way as requests to the API. For hook requests, we provide the signature in the Bz-Signature header. The signature works as authentication, so always verify the signature to prevent unauthorized access. See Authentication for more information about the signature.

The example request is signed using the key 6b3fb3abef828c7d10b5a905a49c988105621395.

We verify the HTTPS server certificate when making webhook requests to your system, so make sure you have a server certificate accepted by common browsers.

The Bz-Hook-Format header contains a version identifier for the webhook format. For slips created via API v2, it always contains v2. For slips previously created using API v1, it contains v1. See Webhook transition for more information on how to migrate webhooks from API v1 to v2.

Download JSON schema

Events

Event Explanation
paid The transaction reached the final paid state and money was collected or paid out. This is a final state. No further state transitions are to be expected.
expired The transaction reached its expiration time without having been paid. No further state transitions are to be expected.
canceled The transaction was invalidated. This is usually executed by the division through the API and therefore it is disabled by default and can only be enabled by viafintech. This is a final state. No further state transitions are to be expected.
declined The transaction was declined after creation. This may occur due to additional e.g. fraud and risk checks that are executed asynchronously. This is a final state. No further state transitions are to be expected. Whether this transition has to be expected depends on the type of transaction. Please contact us if you are unsure whether this applies for your use case.
locked The transaction was scanned at the point of sale. The state of the transaction is still pending unless configured by viafintech to return the locked state. Transactions cannot be canceled and will not automatically expire while they are locked. This event is disabled by default and can only be enabled by viafintech. This is not a final state and may occur more than once for an individual transaction.
unlocked The transaction was unlocked by a point of sale or automatically after a certain time period. Transactions can be canceled again and will automatically expire. This event is disabled by default and can only be enabled by viafintech. This is not a final state and may occur more than once for an individual transaction.
money_received The pay confirmation was received from the retailer. The state of the transaction is still pending as it only transitions to paid after the cooldown period has elapsed. This event is disabled by default and can only be enabled by viafintech. This is not a final state and may occur more than once for an individual transaction.
money_returned The pay confirmation was revoked by the retailer during the cooldown period. This event is disabled by default and can only be enabled by viafintech. This is not a final state and may occur more than once for an individual transaction.

Failed Requests

If a webhook request fails, we retry the request up to 11 times. The waiting time between retries increases exponentially. After at least 24 hours, we give up and send your viafintech App account's administrator an email. The failed webhook can also be viewed and a retry can be initiated in the viafintech App under Transactions / Notifications. For sandbox slips, we do not retry requests (and do not send an email), so they can be viewed immediately in the viafintech App.

We regard all HTTP status codes in the 2xx range as success and everything else as an error. This means redirect status codes like 307 are interpreted as error since we do not follow redirects.

Cooldown period

The cooldown period is a time limit in which our retailers are able to cancel the transaction after we received the pay signal from the retailer. This is in place to allow the retailers to rectify a mistake. For that reason, the paid webhook request is only sent after the cool-down period. The time limit varies depending on the retailer.

In case of using the Know your Customer feature, the cooldown period defaults to 5 minutes.

Errors

Example Error Response

{
  "error_class": "invalid_parameter",
  "error_code": "invalid_slip_type",
  "message": "slip_type: slip_type is required",
  "request_id": "1865359ad354441b9403c3771d811c53"
}

viafintech API v2 returns different HTTP error codes in the 4xx and 5xx ranges. When an error status is returned, the body contains JSON with more information about the error (except for some 5xx errors, which might contain non-JSON data).

Error responses contain an error class as well as an error code. Errors in the same class contain similar types of errors. Your API implementation should be prepared to handle new error codes in any of the existing classes. New error classes will not be added without a new API version. Never write code parsing error messages or use them for anything other than showing them to people. Error messages will change without announcement.

The following describes all error classes as well as all currently used error codes. You should implement automated retries for certain errors, but not for others. Retries are useful not only for certain errors returned by the API, but also for other error cases. See Idempotency for more information.

Download JSON schema

Error Classes

General Errors

The message returned with an error code can contain additional information.

Status Class Code and hints
401 auth invalid_signature
401 auth invalid_signature_format
401 auth only_sandbox_allowed
400 transport invalid_host_header
413 transport request_body_too_large
429 rate_limit rate_limit_exceeded
400 invalid_format invalid_query_params - Query params are not used at the moment.
404 invalid_format invalid_request_url
500 server_error internal_server_error - These should happen rarely, we fix them as soon as possible.

Other HTTP status codes in the 5xx range (e.g. 503) are possible and should be treated the same as a 500 error.

You can find endpoint-specific error codes with the documentation for each endpoint.

Request-Ids

Example Request-Id header

Request-Id: ea65be86bc594a198579c09f16c32681

If you need help with integrating the API and have questions related to a specific request you made, please let us know the Request-Id header in the response. Error responses also contain the request id in their JSON body.

API Stability

We will make backwards-compatible changes to viafintech API v2 without releasing a new version. This means we will not break existing code accessing the API, under the assumption that the existing code allows for the following changes to the API:

If we need to make changes which likely break systems using the API in the future, we will release a new version of the API. Examples for such backwards-incompatible changes are:

Changelog

2024-08-19

2024-05-16

2024-05-06

2024-03-25

2024-01-30

2024-01-21

2024-01-02

2023-08-11

2023-05-25

2023-05-08

2023-03-29

2023-03-24

2023-02-15

2022-12-19

2022-07-28

2022-06-15

2021-01-12

2020-12-03

2020-07-13

2017-04-28

2017-04-21

2017-02-09

2016-09-20

2016-09-09

2016-07-29

Note: The shown dates do not necessarily correspond to the date the change was deployed.

Changes from API v1

Compared to API v1, viafintech API v2 supports several new features and technical improvements.

New Features

Technical Changes

JSON-based REST API

API v2 is a JSON-based REST API and no longer uses XML. This results in a new structure and different endpoints.

We provide JSON schema definitions for request and response bodies.

New slip identifiers

In API v2, slip ids mostly replace transaction ids. Slip ids are strings with a length of up to 50 bytes, while API v1 transaction ids were numeric ids.

A slip represents a token a customer can use to go into a store and pay money in or to get money paid out. A slip usually is a PDF to be printed or a number in a text message. A transaction represents a possible transfer of money. At the moment, a slip created via API v2 must have exactly one transaction.

We built API v2 in a way to make the transition from transaction ids to slip ids as seamless as possible for existing systems. Slips previously created using API v1 (then called transactions) will keep their numeric transaction id, so you can treat existing transactions the same as transactions created using API v2. You can e.g. fetch information about an API v1 slip using the same endpoint as an API v2 slip, GET /slips/12345, with 12345 being a API v1 transaction id. Slips keeping their identifiers also allows you to easily associate webhooks sent with the API v2 format with previously created transactions.

Transaction ids still exist, although, at the moment, they are only necessary to update attributes in a slip's transactions field.

Strings as identifiers

Not only API v2's slip ids are strings, but also transaction and division identifiers are now strings. Although some of the fields might still return only numbers in a string, make sure to treat them as strings with the lengths specified in this documentation. We will change some of the fields to contain non-numeric characters in the future.

Webhook transition

Webhooks in API v2 are always POST requests with a JSON payload.

The old v1 webhook format does not support various fields used in API v2, most importantly slip ids. We thus switch the webhook format to the API v2 format when you create the first slip via API v2.

For slips created via API v2, webhooks are sent in v2 format exclusively. So before using API v2 in production, make sure your production webhooks understand the v2 format.

To allow for a transition period (e.g. during testing), when v2 format is activated, we send webhooks twice for slips created via API v1: Once in v1 format and once in v2 format. This ensures that creating a slip via API v2 doesn't break webhooks for systems still using API v1 and only supporting v1 webhooks.

If you want to prevent your systems reporting errors due to requests they cannot understand, you can decide to ignore webhooks in a certain format by checking the Bz-Hook-Format header. This can be useful for ignoring v1 webhooks after switching to API v2, when there can still be pending transactions created via API v1 before the switch.

When making API v2 webhook requests, we no longer follow redirects. For transitional API v1 webhook requests, we still do.

Other changes

Customer Checkout

viacash checkout overlay example

viacash provides a custom checkout overlay for each payment and payout slip that has been created using the viafintech API v2. You should display this checkout overlay to your customers immediately after they successfully finished their ordering process on your website.

The viacash checkout overlay allows your customers to:

The checkout does not support partial payments, payout and refund slips.

Setup

Example HTML code to display the viacash checkout overlay

<!-- viacash Checkout -->
<script src="https://cdn.viafintech.com/js/v2/checkout.js"
        class="via-checkout"
        data-token="CHECKOUT_TOKEN">
</script>
<!-- End viacash Checkout -->

The checkout overlay is very easy to set up and can be displayed on desktop browsers as well as on mobile phones. All you have to do is the following:

  1. Add the HTML tag <script src="https://cdn.viafintech.com/js/v2/checkout.js" class="via-checkout" data-token="CHECKOUT_TOKEN"> to your website's own checkout page. (This is the page you display to your customers after they have confirmed an order on your website and you received a success response from your request to POST /slips.) You should put the <script ...> tag at the very bottom of your website's HTML source code just before the closing </body> tag. Otherwise some older browsers might not be able to load it properly.
  2. Place the content of the checkout_token that you received within the API response of your call to POST /slips into the data-token attribute of the <script ...> tag.

The <script ...> tag loads a JavaScript file from https://cdn.viafintech.com/js/v2/checkout.js which automatically displays the viacash checkout overlay within a modal on top of your website's own checkout page. The customer is able to close the modal with one click to return to your website.

Reopening the viacash checkout overlay

Allow customers to manually reopen the viacash checkout overlay using a predefined button

<button class="via-checkout-btn">
  Pay now with viacash
</button>

Reopen the viacash checkout overlay using a custom link

<a href="javascript:viaCheckout.display();">
  Pay now with viacash
</a>

As mentioned above, the viacash checkout overlay will open automatically in a modal on your website. Customers are able to close this overlay with a click on the close icon in the top right corner.

In case customers accidentally close the overlay, they might want to reopen it. To allow them to do this, we provide the following two possibilities:

  1. Include the following code into the HTML of your own checkout page: <button class="via-checkout-btn">Pay now with viacash.de</button>. This will render a pre-styled button that, when clicked by the customer, reopens the viacash checkout overlay. (Make sure to include the <button ...> on the same page as the <script ...> tag, as it will not work otherwise.)
  2. In case you want to be more flexible (e.g. you want to use your own styled button or a link tag instead) you can reopen the viacash checkout overlay using the JavaScript function viaCheckout.display().

Disable automatic display

Example HTML code to disable the automatic display of the viacash checkout overlay

<!-- viacash Checkout -->
<script src="https://cdn.viafintech.com/js/v2/checkout.js"
        class="via-checkout"
        data-token="CHECKOUT_TOKEN"
        data-auto-display="false">
</script>
<!-- End viacash Checkout -->

Under certain circumstances it might be useful to prevent the checkout overlay from appearing automatically. Add the optional attribute data-auto-display="false" to the <script ...> tag to achieve this result. Not specifying the data-auto-display attribute at all or setting it to "true" will automatically display the checkout overlay. We recommend to always display the checkout overlay automatically to make it as easy as possible for your customers to immediately see all relevant information related to their viacash payment or payout process.

If you decide to disable the automatic display, make sure to allow your customers to manually open the checkout overlay using a predefined button or custom link like explained above.

Sandbox

Example HTML code to display the viacash checkout overlay in sandbox mode

<!-- viacash Checkout Sandbox -->
<script src="https://cdn.viafintech.com/js/v2/checkout-sandbox.js"
        class="via-checkout"
        data-token="CHECKOUT_TOKEN">
</script>
<!-- End viacash Checkout Sandbox -->

To use the viacash checkout overlay in sandbox mode, you need to change the src parameter of the HTML tag to point to a different JavaScript file: <script src="https://cdn.viafintech.com/js/v2/checkout-sandbox.js" class="via-checkout" data-token="CHECKOUT_TOKEN">

/ping

Ping

GET /ping

The /ping endpoint allows verifying that the connection to viafintech and authentication work. Calling this endpoint does not change any server state and always returns an empty JSON object for a valid request.

Using this endpoint is optional, there is no need to call it before accessing other endpoints of the API.

Example Response Body for HTTP status 200 with Content-Type application/json

{}

Headers

Header Description
Authorization A per-request signature for authentication, see Authentication.

Errors

General API Errors can also be returned by this resource. See also Errors.

/slips

Create Slip

POST /slips

Example Minimal Request Body for a payment slip

{
  "slip_type": "payment",
  "customer": {
    "key": "LDFKHSLFDHFL"
  },
  "transactions": [
    { "currency": "EUR", "amount": "123.34" }
  ]
}

Create a payment, partial payments, payout, or refund slip.

If you provide an email address, we send an email with a PDF attachment to the customer. If you provide a cell phone number for a payment or partial payments slip, we send a text message containing the barcode number and the amount. If specified in our contractual agreement, we also send text messages for payouts. We do not send text messages for refunds.

Note: The Idempotency-Key header is required for this endpoint. See below.

Payment Slips

Payment slips can be paid by a customer and result in money being transferred to your division. They are used e.g. when a customer orders a product in an online shop.

Payment slip specifics:

Partial Payment Slips

Example Minimal Request Body for a partial payments slip

{
  "slip_type": "partial_payments",
  "customer": {
    "key": "LDFKHSLFDHFL"
  },
  "transactions": [
    { "currency": "EUR", "amount": "123.34", "displayed_due_at": "2020-05-31T22:00:00Z" },
    { "currency": "EUR", "amount": "123.34", "displayed_due_at": "2020-06-30T22:00:00Z" }
  ]
}

Partial Payment slips can be paid by a customer and result in money being transferred to your division for each individual payment. They are used e.g. when a customer pays their monthly electricity bill.

Partial Payment slip specifics:

Payout Slips

Example Minimal Request Body for a payout slip

{
  "slip_type": "payout",
  "customer": {
    "key": "LDFKHSLFDHFL"
  },
  "transactions": [
    { "currency": "EUR", "amount": "-123.34" }
  ]
}

Payout slips allow a customer to receive money and result in money being transferred from your division. They are used when paying out money that is not associated with a previous payment. When returning a portion or all of the money a customer has previously paid via viacash, use refund slips.

Payout slip specifics:

Refund Slips

Example Minimal Request Body for a refund slip

{
  "slip_type": "refund",
  "refund": {
    "for_slip_id": "slp-d90ab05c-69f2-4e87-9972-97b3275a0ccd"
  },
  "transactions": [
    { "currency": "EUR", "amount": "-23.99" }
  ]
}

Refund slips return money to a customer and must be associated with a payment slip the same customer previously paid. They are used e.g. when a customer has returned a product to an online shop. The sum of all refund slip's amounts associated with a single payment slip must be less than or equal to the payment slip's amount.

Refund slip specifics:

KYC Attributes

Example Request Body for a payment slip with KYC attributes

{
  "slip_type": "payment",
  "customer": {
    "key": "LDFKHSLFDHFL",
    "ip_address": "46.231.176.208",
    "cell_phone": "+49123456789",
    "email": "john@example.com",
    "language": "de-DE",
    "first_name": "John",
    "last_name": "Doe",
    "date_of_birth": "1990-12-31",
    "place_of_birth": "Berlin",
    "address": {
      "street_and_no": "Budapester Str. 50",
      "zipcode": "10178",
      "city": "Berlin",
      "country": "DE"
    },
    "tax_id": "12 345 678 901",
    "document": {
      "type": "passport",
      "issuing_authority": "Buergeramt",
      "id_number": "T22000129",
      "date_of_issuance": "2020-01-01",
      "date_of_expiry": "2022-01-01"
    }
  },
  "country": "DE",
  "transactions": [
    { "currency": "EUR", "amount": "123.34" }
  ]
}

Further attributes need to be added to the customer if KYC information are required. key, cell_phone, email and language attributes are not considered as KYC attributes.

These fields are not accepted by default. See Optional Features for more information.

Example Request Body

{
  "slip_type": "payment",
  "reference_key": "O64737X",
  "hook_url": "https://psp.example.com/hook",
  "expires_at": "2016-01-10T12:34:56Z",
  "customer": {
    "key": "LDFKHSLFDHFL",
    "cell_phone": "+49123456789",
    "email": "john@example.com",
    "language": "de-DE",
  },
  "show_stores_near": {
    "address": {
      "street_and_no": "Budapester Str. 50",
      "zipcode": "10787",
      "city": "Berlin",
      "country": "DE"
    }
  },
  "metadata": {
    "order_id": "1234",
    "invoice_no": "A123"
  },
  "transactions": [
    {
      "currency": "EUR",
      "amount": "123.34",
      "displayed_due_at": "2016-01-10T12:34:56Z"
    }
  ]
}

Request Attributes

Name Type Description Example
country nullable string Country in which the transactions of the slip should be payable as two-letter ISO 3166-1 alpha 2 language code. Defaults to system configuration if not given. This field is not accepted by default. See Optional Features for more information.
Pattern: ^[A-Z]+$
Length: 2
"DE"
customer:​address:​city nullable string The customer's city. May be provided in Latin, Cyrillic, Greek and Georgian letters. This field is not accepted by default. See Optional Features for more information.
Pattern: ^[\p{Latin}\p{Cyrillic}\p{Greek}\p{Georgian}0-9()&_+\./:,-\\\?\!'‘’ ]*$
Length: 1..80
"Berlin"
customer:​address:​country nullable string The customer's country, a ISO 3166-1 alpha 2 language code. This field is not accepted by default. See Optional Features for more information.
Pattern: ^[A-Z]+$
Length: 2
"DE"
customer:​address:​street_and_no nullable string The customer's street and house number. May be provided in Latin, Cyrillic, Greek and Georgian letters. This field is not accepted by default. See Optional Features for more information.
Pattern: ^[\p{Latin}\p{Cyrillic}\p{Greek}\p{Georgian}0-9()&_+\./:,-\\\?\!#'‘’ ]*$
Length: 1..105
"Budapester Str. 50"
customer:​address:​zipcode nullable string The customer's zip code. This field is not accepted by default. See Optional Features for more information.
Pattern: ^[0-9a-zA-Z -]+$
Length: 1..10
"10787"
customer:​cell_phone nullable string The customer's cell phone number in international format. For payment slips, triggers a text message being sent if provided.
Pattern: ^\+[0-9]+$
Length: 9..19
"+49151123456789"
customer:​coordinates:​lat nullable string The customer's geographical latitude when creating a slip.
Pattern: ^(-?[1-8]?[0-9]\.\d{1,10}|90\.0{1,10})$
"52.123"
customer:​coordinates:​lng nullable string The customer's geographical longitude when creating a slip.
Pattern: ^(-?(1[0-7][0-9]|[1-9]?[0-9])\.\d{1,10}?|180\.0{1,10}?)$
"10.123"
customer:​date_of_birth nullable full-date The customer's date of birth. Format is full-date as defined in RFC 3339 Section 5.6. This field is not accepted by default. See Optional Features for more information.
Pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}$
"1990-12-31"
customer:​document:​date_of_expiry nullable full-date The expiry date of the document. Format is full-date as defined in RFC 3339 Section 5.6. This field is not accepted by default. See Optional Features for more information.
Pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}$
"2025-01-01"
customer:​document:​date_of_issuance nullable full-date The issuance date of the document. Format is full-date as defined in RFC 3339 Section 5.6. This field is not accepted by default. See Optional Features for more information.
Pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}$
"2020-01-01"
customer:​document:​id_number nullable string The ID number of the document. This field is not accepted by default. See Optional Features for more information.
Length: 1..80
"T22000129"
customer:​document:​issuing_authority nullable string The issuing authority of the document. This field is not accepted by default. See Optional Features for more information.
Length: 1..80
"Buergeramt"
customer:​document:​type string The customer's chosen document type. This field is not accepted by default. See Optional Features for more information.
One of: "passport" or "national_id_card" or "driving_license" or "residence_permit"
"passport"
customer:​email nullable idn-email The customer's email address. Triggers an email being sent if provided.
Length: 3..80
"john@example.com"
customer:​first_name nullable string The customer's first name. May be provided in Latin, Cyrillic, Greek and Georgian letters. This field is not accepted by default. See Optional Features for more information.
Pattern: ^[\p{Latin}\p{Cyrillic}\p{Greek}\p{Georgian}()&_+\./:,-\\\?\!'‘’ ]*$
Length: 1..80
"John"
customer:​ip_address nullable string The customer's IP address used to access the services of the division. Must be either a valid IPv4 (e.g. 46.231.176.208) or IPv6 (e.g. 2001:db8::1) address. This field is not accepted by default. See Optional Features for more information.
Length: 0..45
"46.231.176.208"
customer:​key nullable string A key uniquely identifying the customer. See Identifying a customer for more information.
Pattern: ^[a-zA-Z0-9!"#\$%&'()*+,-\./:;<=>\?@\[\\\]\^_\{\|\}~]+$
Length: 0..80
"LDFKHSLFDHFL"
customer:​kyc_type nullable string The customer's type of kyc. This field is not accepted by default. See Optional Features for more information.
One of: "kyc" or "e_kyc" or "kyb"
"kyc"
customer:​language nullable string The language used for communicating with the customer (e.g. for email, text message, web interface). RFC 5646 language-region code, only the values in the list below are supported at the moment.
One of: null or "de-DE" or "de-CH" or "el-GR" or "en-CH" or "es-ES" or "fr-FR" or "it-IT"
"de-DE"
customer:​last_name nullable string The customer's last name. May be provided in Latin, Cyrillic, Greek and Georgian letters. This field is not accepted by default. See Optional Features for more information.
Pattern: ^[\p{Latin}\p{Cyrillic}\p{Greek}\p{Georgian}()&_+\./:,-\\\?\!'‘’ ]*$
Length: 1..80
"Smith"
customer:​mcc nullable string The MCC is used to categorize the customer's business when the kyc_type is kyb. This field is not accepted by default. See Optional Features for more information.
Pattern: ^[0-9]+$
Length: 4
"4900"
customer:​place_of_birth nullable string The customer's place of birth. May be provided in Latin, Cyrillic, Greek and Georgian letters. This field is not accepted by default. See Optional Features for more information.
Pattern: ^[\p{Latin}\p{Cyrillic}\p{Greek}\p{Georgian}0-9()&_+\./:,-\\\?\!'‘’ ]*$
Length: 0..80
"Berlin"
customer:​tax_id nullable string The customer's tax id. This field is not accepted by default. See Optional Features for more information.
Length: 0..40
"12 345 678 901"
expires_at nullable date-time Time the slip expires and can no longer be used. Strongly recommended if specific preferences need to be set. Will be set automatically depending on your contract if not provided. For partial_payments will be set to latest displayed_due_at if not provided. Format is date-time as defined in RFC 3339 Section 5.6.
Pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(|\.[0-9]+)(Z|[\+-][0-9]{2}:[0-9]{2})$
"2015-01-01T12:00:00Z"
hook_url nullable uri Per-slip webhook URL to use instead of the one configured in the viafintech App. See Webhooks.
Pattern: ^https://[a-zA-Z0-9!"#\$%&'()*+,-\./:;<=>\?@\[\\\]\^_\{\|\}~]+$
Length: 0..512
null
metadata nullable object Custom metadata not processed by viafintech, returned in responses and webhooks. Useful for associating slips with internal identifiers, see also reference_key. Maximum 3 keys, max. 15 bytes key length and max. 50 bytes value length. Keys and values must be strings. null
reference_key nullable string A key referencing an order or another internal process. Must be unique per payment, partial_payments, or payout slip, and division (or null).
Pattern: ^[a-zA-Z0-9!"#\$%&'()*+,-\./:;<=>\?@\[\\\]\^_\{\|\}~]+$
Length: 0..40
"O64737X"
refund:​for_slip_id string For refunds, must reference a payment slip's id. See 'Refund Slips' above.
Pattern: ^([0-9]+|slp\-[a-z\-0-9]+)$
Length: 1..50
"2738529243"
show_stores_near:​address:​city string The customer's city for showing nearby stores. See above for more information about providing an address.
Length: 1..50
"Berlin"
show_stores_near:​address:​country string The customer's country for showing nearby stores, a ISO 3166-1 alpha 2 language code.
Pattern: ^[A-Z]+$
Length: 0..2
"DE"
show_stores_near:​address:​street_and_no string The customer's street and house number for showing nearby stores.
Length: 1..60
"Budapester Straße 50"
show_stores_near:​address:​zipcode string The customer's zip code for showing nearby stores.
Pattern: ^[0-9a-zA-Z -]+$
Length: 0..10
"10787"
slip_type string Slip type, see above.
One of: "payment" or "partial_payments" or "payout" or "refund"
"payment"
transactions/​amount string Amount to be paid in/out with a dot as decimal separator and maximum of two decimal places. Negative when paying out money.
Pattern: ^-?[0-9]+\.[0-9]+$
"123.34"
transactions/​currency string Currency as three-letter ISO 4217 code. The allowed currencies depend on your configuration.
One of: "EUR" or "CHF" or "BGN" or "CZK" or "HUF" or "PLN" or "RON" or "SEK" or "GBP"
"EUR"
transactions/​displayed_due_at nullable date-time Time displayed on the slip until which the individual transaction should be paid. Required for partial_payments. Not accepted for payments, payouts, and refunds. Must be at or before expires_at. Format is date-time as defined in RFC 3339 Section 5.6.
Pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(|\.[0-9]+)(Z|[\+-][0-9]{2}:[0-9]{2})$
"2015-01-01T12:00:00Z"

Download JSON schema

Example Response Body for HTTP status 201 with Content-Type application/json

{
  "id": "slp-d90ab05c-69f2-4e87-9972-97b3275a0ccd",
  "slip_type": "payment",
  "division_id": "1234",
  "reference_key": "O64737X",
  "hook_url": "https://psp.example.com/hook",
  "expires_at": "2016-01-10T12:34:56Z",
  "customer": {
    "key": "LDFKHSLFDHFL",
    "cell_phone_last_4_digits": "6789",
    "email": "john@example.com",
    "language": "de-DE"
  },
  "checkout_token": "djF8Y2hrdHxzbHAtMTM4ZWI3NzUtOWY5Yy00NzYwLWI4ZTAtYTNlZWNmYjQ5M2IxfElBSThZMnd6SFYwbjJpMm9aSUpvREpnYnhNS3c5Z2x3elJOanlLblZJeFk9",
  "metadata": {
    "order_id": "1234",
    "invoice_no": "A123"
  },
  "transactions": [
    {
      "id": "4729294329",
      "currency": "EUR",
      "amount": "123.34",
      "displayed_due_at": "2016-01-10T12:34:56Z",
      "state": "pending",
      "country": null
    }
  ],
  "nearest_stores": [
    {
      "title": "mobilcom-debitel",
      "logo": {
        "id": "17077"
      },
      "distance_m": 1160,
      "address": {
        "city": "Berlin",
        "country": "DE",
        "street_and_no": "Grunerstraße 20",
        "zipcode": "10179"
      },
      "opening_hours": {
        "days": [
          { "day": "sun", "open": [] },
          { "day": "mon", "open": [{"begin": "10:00", "end": "21:00"}] },
          { "day": "tue", "open": [{"begin": "10:00", "end": "21:00"}] },
          { "day": "wed", "open": [{"begin": "10:00", "end": "21:00"}] },
          { "day": "thu", "open": [{"begin": "10:00", "end": "21:00"}] },
          { "day": "fri", "open": [{"begin": "10:00", "end": "21:00"}] },
          { "day": "sat", "open": [{"begin": "10:00", "end": "21:00"}] }
        ]
      }
    },
    {
      "title": "dm-drogerie markt",
      "logo": {
        "id": "13045"
      },
      "distance_m": 1220,
      "address": {
        "city": "Berlin",
        "country": "DE",
        "street_and_no": "Alexanderplatz 1",
        "zipcode": "10178"
      },
      "opening_hours": {
        "days": [
          { "day": "sun", "open": [] },
          { "day": "mon", "open": [{"begin": "09:00", "end": "22:00"}] },
          { "day": "tue", "open": [{"begin": "09:00", "end": "22:00"}] },
          { "day": "wed", "open": [{"begin": "09:00", "end": "22:00"}] },
          { "day": "thu", "open": [{"begin": "09:00", "end": "22:00"}] },
          { "day": "fri", "open": [{"begin": "09:00", "end": "22:00"}] },
          { "day": "sat", "open": [{"begin": "09:00", "end": "22:00"}] }
        ]
      }
    },
    {
      "title": "dm-drogerie markt",
      "logo": {
        "id": "13045"
      },
      "distance_m": 1280,
      "address": {
        "city": "Berlin",
        "country": "DE",
        "street_and_no": "Henriette-Herz-Platz 4",
        "zipcode": "10178"
      },
      "opening_hours": {
        "days": [
          { "day": "sun", "open": [] },
          { "day": "mon", "open": [{"begin": "08:30", "end": "21:00"}] },
          { "day": "tue", "open": [{"begin": "08:30", "end": "21:00"}] },
          { "day": "wed", "open": [{"begin": "08:30", "end": "21:00"}] },
          { "day": "thu", "open": [{"begin": "08:30", "end": "21:00"}] },
          { "day": "fri", "open": [{"begin": "08:30", "end": "21:00"}] },
          { "day": "sat", "open": [{"begin": "09:00", "end": "21:00"}] }
        ]
      }
    }
  ]
}

Response Attributes

Name Type Description Example
barcode_code128 string This number represents the barcode the customer gives to a cashier in a store. This field is not returned by default. See Optional Features for more information.
Pattern: ^[0-9]{13,40}$
Length: 13..40
"4051234567890"
barcode_ean13 string This number represents the barcode the customer gives to a cashier in a store. This field is not returned by default. See Optional Features for more information.
Pattern: ^[0-9]{13}$
Length: 13
"4051234567890"
checkout_token string Token used for displaying the viacash checkout page. The field is only returned in responses to POST /slips requests with a payment or payout slip_type, but not for other endpoints or slip types.
Length: 20..255
"djF8Y2hrdHxzbH..."
customer:​cell_phone_last_4_digits nullable string Last 4 digits of the customer's cell phone number (cut off for privacy reasons)
Pattern: ^[0-9]*$
Length: 4
"6789"
customer:​email nullable string The customer's email address.
Length: 3..88
"john@example.com"
customer:​key string A key uniquely identifying the customer. See Identifying a customer for more information.
Pattern: ^[a-zA-Z0-9!"#\$%&'()*+,-\./:;<=>\?@\[\\\]\^_\{\|\}~]+$
Length: 0..40
"LDFKHSLFDHFL"
customer:​language string The language used for communicating with the customer (e.g. for email, text message, web interface) (RFC 5646 language-region code).
Pattern: ^[a-z]{2}-[A-Z]{2}$
"de-DE"
division_id string A string identifying the division that created the slip. A division can only access their own slips, so this is always the same per API key.
Length: 1..50
"1234"
expires_at date-time Time the slip expires and can no longer be used. Format is date-time as defined in RFC 3339 Section 5.6. "2015-01-01T12:00:00Z"
hook_url nullable string Per-slip webhook URL to use instead of the one configured in the viafintech App. See Webhooks. null
id string A string identifying a slip.
Length: 1..50
"slp-d90ab05c-69f2-4e87-9972-97b3275a0ccd"
metadata object Custom metadata not processed by viafintech, useful for associating slips with internal identifiers. Keys and values are strings.
nearest_stores/​address:​city string The store's city.
Length: 1..255
"Berlin"
nearest_stores/​address:​country string The store's country, a ISO 3166-1 alpha 2 language code.
Pattern: ^[A-Z]+$
Length: 0..2
"DE"
nearest_stores/​address:​street_and_no string The store's street and house number.
Length: 0..255
"Budapester Str. 50"
nearest_stores/​address:​zipcode string The store's zip code.
Length: 0..10
"10787"
nearest_stores/​distance_m integer Distance in meters from the given address to the store. Note that for refunds, we currently ignore the address given when creating the refund and use the address given when creating the original payment. 42
nearest_stores/​logo:​id string A unique identifier for a logo related to the store. Please contact us if you want to use store logos.
Length: 1..50
"example"
nearest_stores/​opening_hours:​days/​day string The day of week the opening hours are valid for. Note that the JSON objects describing the different weekdays are always ordered, beginning with Sunday. You do not necessarily have to evaluate this field, but can assume that the first object in the 'days' array refers to Sunday, the second to Monday, and so on.
One of: "sun" or "mon" or "tue" or "wed" or "thu" or "fri" or "sat"
"sun"
nearest_stores/​opening_hours:​days/​open/​begin string Time the store opens. Stores may open multiple times a day, so the 'open' array can contain multiple elements.
Pattern: ^[0-9]{2}:[0-9]{2}$
"example"
nearest_stores/​opening_hours:​days/​open/​end string Time the store closes.
Pattern: ^[0-9]{2}:[0-9]{2}$
"example"
nearest_stores/​title string The store's name.
Length: 1..120
"example"
reference_key nullable string A key referencing an order or another internal process.
Pattern: ^[a-zA-Z0-9!"#\$%&'()*+,-\./:;<=>\?@\[\\\]\^_\{\|\}~]+$
Length: 0..40
"O64737X"
refund:​for_slip_id string For refunds, references a payment slip's id. See 'Refund Slips' above.
Length: 1..50
"slp-d90ab05c-69f2-4e87-9972-97b3275a0ccd"
slip_type string Slip type, see above.
One of: "payment" or "payout" or "refund"
"payment"
transactions/​amount string Amount with a dot as decimal separator and maximum of two decimal places. Negative when paying out money.
Pattern: ^-?[0-9]+\.[0-9]+$
"123.34"
transactions/​country nullable string Country in which a transaction was scanned and paid as two-letter ISO 3166-1 alpha 2 language code.
Length: 2
"DE"
transactions/​currency string Currency as three-letter ISO 4217 code.
Length: 3
"EUR"
transactions/​displayed_due_at date-time Time defining the expected time until which the transaction should be paid. Format is date-time as defined in RFC 3339 Section 5.6. "2015-01-01T12:00:00Z"
transactions/​id string A string identifying a transaction. As with all values in this API returned as string, if you need to store this, make sure to store it as a string.
Length: 1..50
"4729294329"
transactions/​state string A transaction's state. Only pending transactions can be modified.
One of: "pending" or "locked" or "paid" or "expired" or "invalidated" or "declined"
"pending"

Download JSON schema

Headers

Header Description
Authorization A per-request signature for authentication, see Authentication.
Idempotency-Key A required random string unique per slip to be created, see Idempotency.

Errors

General API Errors can also be returned by this resource. See also Errors.

Status Class Code and hints
400 idempotency invalid_idempotency_key
400 idempotency reused_idempotency_key - Key reused with different parameters
415 invalid_format request_body_not_valid_json
400 invalid_format unknown_additional_parameter
400 invalid_state associated_slip_not_found - For refunds only, the payment slip could not be found.
400 invalid_state associated_slip_not_a_payment - For refunds only.
400 invalid_state associated_slip_not_paid - For refunds only.
400 invalid_state associated_slip_anonymized - For refunds only, the payment slip has been anonymized.
400 invalid_state reference_key_already_exists - Your division is configured to not allow duplicate reference keys.
400 invalid_parameter request_body_not_a_json_object
400 invalid_parameter customer_cell_phone_not_settable
400 invalid_parameter customer_email_not_settable
400 invalid_parameter customer_key_not_settable
400 invalid_parameter customer_ip_address_not_settable
400 invalid_parameter customer_language_not_settable
400 invalid_parameter reference_key_not_settable
400 invalid_parameter transactions_displayed_due_at_not_settable - For payments, payouts, and refunds only
400 invalid_parameter invalid_slip_type
400 invalid_parameter invalid_refund
400 invalid_parameter invalid_refund_for_slip_id
400 invalid_parameter invalid_hook_url
400 invalid_parameter invalid_expires_at
400 invalid_parameter invalid_country
400 invalid_parameter invalid_customer
400 invalid_parameter invalid_customer_key
400 invalid_parameter invalid_customer_ip_address
400 invalid_parameter invalid_customer_cell_phone
400 invalid_parameter invalid_customer_email
400 invalid_parameter invalid_customer_first_name
400 invalid_parameter invalid_customer_last_name
400 invalid_parameter invalid_customer_date_of_birth
400 invalid_parameter invalid_customer_place_of_birth
400 invalid_parameter invalid_customer_address
400 invalid_parameter invalid_customer_address_street_and_no
400 invalid_parameter invalid_customer_address_zipcode
400 invalid_parameter invalid_customer_address_city
400 invalid_parameter invalid_customer_address_country
400 invalid_parameter invalid_customer_coordinates
400 invalid_parameter invalid_customer_coordinates_lat
400 invalid_parameter invalid_customer_coordinates_lng
400 invalid_parameter invalid_customer_language
400 invalid_parameter invalid_customer_mcc
400 invalid_parameter invalid_customer_tax_id
400 invalid_parameter invalid_customer_kyc_type
400 invalid_parameter invalid_customer_document
400 invalid_parameter invalid_customer_document_type
400 invalid_parameter invalid_customer_document_issuing_authority
400 invalid_parameter invalid_customer_document_id_number
400 invalid_parameter invalid_customer_document_date_of_issuance
400 invalid_parameter invalid_customer_document_date_of_expiry
400 invalid_parameter invalid_metadata
400 invalid_parameter invalid_show_stores_near
400 invalid_parameter invalid_show_stores_near_address_street_and_no
400 invalid_parameter invalid_show_stores_near_address_zipcode
400 invalid_parameter invalid_show_stores_near_address_city
400 invalid_parameter invalid_show_stores_near_address_country
400 invalid_parameter invalid_transactions
400 invalid_parameter invalid_transactions_currency
400 invalid_parameter invalid_transactions_amount
400 invalid_parameter invalid_transactions_displayed_due_at
400 invalid_parameter too_early_transactions_displayed_due_at
400 invalid_parameter transactions_displayed_due_at_after_expires_at
400 invalid_parameter too_late_transactions_displayed_due_at
400 invalid_parameter too_early_expires_at
400 invalid_parameter too_late_expires_at
403 not_allowed legal_amount_limit_exceeded - For legal reasons, we are only allowed to process a certain amount per time.
403 not_allowed slip_type_not_allowed - Contact us if you want to use a slip type currently not allowed for your division.
403 not_allowed country_not_allowed - Country limitations are not enabled for your division. Contact us if want to enable it for your division. Country limitations are automatically enabled when KYC is enabled.
403 not_allowed customer_first_name_not_allowed - KYC is not enabled for your division. Contact us if you want to enable KYC for your division.
403 not_allowed customer_last_name_not_allowed - KYC is not enabled for your division. Contact us if you want to enable KYC for your division.
403 not_allowed customer_date_of_birth_not_allowed - KYC is not enabled for your division. Contact us if you want to enable KYC for your division.
403 not_allowed customer_place_of_birth_not_allowed - KYC is not enabled for your division. Contact us if you want to enable KYC for your division.
403 not_allowed customer_address_street_and_no_not_allowed - KYC is not enabled for your division. Contact us if you want to enable KYC for your division.
403 not_allowed customer_address_zipcode_not_allowed - KYC is not enabled for your division. Contact us if you want to enable KYC for your division.
403 not_allowed customer_address_city_not_allowed - KYC is not enabled for your division. Contact us if you want to enable KYC for your division.
403 not_allowed customer_address_country_not_allowed - KYC is not enabled for your division. Contact us if you want to enable KYC for your division.
403 not_allowed customer_tax_id_not_allowed - KYC is not enabled for your division. Contact us if you want to enable KYC for your division.
403 not_allowed customer_mcc_not_allowed - Sending customer mcc when customer KYCType is not kyb is not allowed
403 not_allowed customer_document_type_not_allowed - KYC is not enabled for your division. Contact us if you want to enable KYC for your division.
403 not_allowed customer_document_issuing_authority_not_allowed - KYC is not enabled for your division. Contact us if you want to enable KYC for your division.
403 not_allowed customer_document_id_number_not_allowed - KYC is not enabled for your division. Contact us if you want to enable KYC for your division.
403 not_allowed customer_document_date_of_issuance_not_allowed - KYC is not enabled for your division. Contact us if you want to enable KYC for your division.
403 not_allowed customer_document_date_of_expiry_not_allowed - KYC is not enabled for your division. Contact us if you want to enable KYC for your division.
403 not_allowed available_payout_amount_insufficient - Your division's available amount for refunds / payouts is insufficient.
403 not_allowed associated_payment_amount_exceeded - The sum of refunds would exceed the sum of the associated payment slip.
403 not_allowed payout_amount_limit_exceeded - The sum of payouts (not refunds) would exceed a rolling per-client and per-customer limit.
403 not_allowed suspected_risk_aml_transaction_declined - The transaction or the customer has been labeled as a potential part of suspected fraud or financial crime activity. The customer might be able to create a new transaction.
403 not_allowed confirmed_risk_aml_transaction_declined - The transaction or the customer has been identified with confirmed fraud or financial crime activity. The customer is unable to create any new transactions or execute any further actions.
403 not_allowed transaction_creation_declined_due_to_sanction_screening - The transaction was declined due to sanction screening.
403 not_allowed customer_locked - The customer is unable to create any new transactions or execute any further actions.
403 not_allowed customer_document_not_allowed - Sending customer documents when customer KYCType is e_kyc is not allowed
429 rate_limit transaction_creation_rate_limit_exceeded - Your division has created more transactions per time than allowed. See Transaction Limit for more information.

Retrieve Slip

GET /slips/{id}

Retrieve information about a slip.

Example Response Body for HTTP status 200 with Content-Type application/json

{
  "id": "slp-d90ab05c-69f2-4e87-9972-97b3275a0ccd",
  "slip_type": "payment",
  "division_id": "1234",
  "reference_key": "O64737X",
  "hook_url": "https://psp.example.com/hook",
  "expires_at": "2016-01-10T12:34:56Z",
  "customer": {
    "key": "LDFKHSLFDHFL",
    "cell_phone_last_4_digits": "6789",
    "email": "john@example.com",
    "language": "de-DE"
  },
  "metadata": {
    "order_id": "1234",
    "invoice_no": "A123"
  },
  "transactions": [
    {
      "id": "4729294329",
      "currency": "EUR",
      "amount": "123.34",
      "displayed_due_at": "2020-06-12T07:32:19Z",
      "state": "pending",
      "country": "DE"
    }
  ],
  "nearest_stores": [
    {
      "title": "mobilcom-debitel",
      "logo": {
        "id": "17077"
      },
      "distance_m": 1160,
      "address": {
        "city": "Berlin",
        "country": "DE",
        "street_and_no": "Grunerstraße 20",
        "zipcode": "10179"
      },
      "opening_hours": {
        "days": [
          { "day": "sun", "open": [] },
          { "day": "mon", "open": [{"begin": "10:00", "end": "21:00"}] },
          { "day": "tue", "open": [{"begin": "10:00", "end": "21:00"}] },
          { "day": "wed", "open": [{"begin": "10:00", "end": "21:00"}] },
          { "day": "thu", "open": [{"begin": "10:00", "end": "21:00"}] },
          { "day": "fri", "open": [{"begin": "10:00", "end": "21:00"}] },
          { "day": "sat", "open": [{"begin": "10:00", "end": "21:00"}] }
        ]
      }
    },
    {
      "title": "dm-drogerie markt",
      "logo": {
        "id": "13045"
      },
      "distance_m": 1220,
      "address": {
        "city": "Berlin",
        "country": "DE",
        "street_and_no": "Alexanderplatz 1",
        "zipcode": "10178"
      },
      "opening_hours": {
        "days": [
          { "day": "sun", "open": [] },
          { "day": "mon", "open": [{"begin": "09:00", "end": "22:00"}] },
          { "day": "tue", "open": [{"begin": "09:00", "end": "22:00"}] },
          { "day": "wed", "open": [{"begin": "09:00", "end": "22:00"}] },
          { "day": "thu", "open": [{"begin": "09:00", "end": "22:00"}] },
          { "day": "fri", "open": [{"begin": "09:00", "end": "22:00"}] },
          { "day": "sat", "open": [{"begin": "09:00", "end": "22:00"}] }
        ]
      }
    },
    {
      "title": "dm-drogerie markt",
      "logo": {
        "id": "13045"
      },
      "distance_m": 1280,
      "address": {
        "city": "Berlin",
        "country": "DE",
        "street_and_no": "Henriette-Herz-Platz 4",
        "zipcode": "10178"
      },
      "opening_hours": {
        "days": [
          { "day": "sun", "open": [] },
          { "day": "mon", "open": [{"begin": "08:30", "end": "21:00"}] },
          { "day": "tue", "open": [{"begin": "08:30", "end": "21:00"}] },
          { "day": "wed", "open": [{"begin": "08:30", "end": "21:00"}] },
          { "day": "thu", "open": [{"begin": "08:30", "end": "21:00"}] },
          { "day": "fri", "open": [{"begin": "08:30", "end": "21:00"}] },
          { "day": "sat", "open": [{"begin": "09:00", "end": "21:00"}] }
        ]
      }
    }
  ]
}

Response Attributes

Name Type Description Example
barcode_code128 string This number represents the barcode the customer gives to a cashier in a store. This field is not returned by default. See Optional Features for more information.
Pattern: ^[0-9]{13,40}$
Length: 13..40
"4051234567890"
barcode_ean13 string This number represents the barcode the customer gives to a cashier in a store. This field is not returned by default. See Optional Features for more information.
Pattern: ^[0-9]{13}$
Length: 13
"4051234567890"
customer:​cell_phone_last_4_digits nullable string Last 4 digits of the customer's cell phone number (cut off for privacy reasons)
Pattern: ^[0-9]*$
Length: 4
"6789"
customer:​email nullable string The customer's email address.
Length: 3..88
"john@example.com"
customer:​key string A key uniquely identifying the customer. See Identifying a customer for more information.
Pattern: ^[a-zA-Z0-9!"#\$%&'()*+,-\./:;<=>\?@\[\\\]\^_\{\|\}~]+$
Length: 0..40
"LDFKHSLFDHFL"
customer:​language string The language used for communicating with the customer (e.g. for email, text message, web interface) (RFC 5646 language-region code).
Pattern: ^[a-z]{2}-[A-Z]{2}$
"de-DE"
division_id string A string identifying the division that created the slip. A division can only access their own slips, so this is always the same per API key.
Length: 1..50
"1234"
expires_at date-time Time the slip expires and can no longer be used. Format is date-time as defined in RFC 3339 Section 5.6. "2015-01-01T12:00:00Z"
hook_url nullable string Per-slip webhook URL to use instead of the one configured in the viafintech App. See Webhooks. null
id string A string identifying a slip.
Length: 1..50
"slp-d90ab05c-69f2-4e87-9972-97b3275a0ccd"
metadata object Custom metadata not processed by viafintech, useful for associating slips with internal identifiers. Keys and values are strings.
nearest_stores/​address:​city string The store's city.
Length: 1..255
"Berlin"
nearest_stores/​address:​country string The store's country, a ISO 3166-1 alpha 2 language code.
Pattern: ^[A-Z]+$
Length: 0..2
"DE"
nearest_stores/​address:​street_and_no string The store's street and house number.
Length: 0..255
"Budapester Str. 50"
nearest_stores/​address:​zipcode string The store's zip code.
Length: 0..10
"10787"
nearest_stores/​distance_m integer Distance in meters from the given address to the store. Note that for refunds, we currently ignore the address given when creating the refund and use the address given when creating the original payment. 42
nearest_stores/​logo:​id string A unique identifier for a logo related to the store. Please contact us if you want to use store logos.
Length: 1..50
"example"
nearest_stores/​opening_hours:​days/​day string The day of week the opening hours are valid for. Note that the JSON objects describing the different weekdays are always ordered, beginning with Sunday. You do not necessarily have to evaluate this field, but can assume that the first object in the 'days' array refers to Sunday, the second to Monday, and so on.
One of: "sun" or "mon" or "tue" or "wed" or "thu" or "fri" or "sat"
"sun"
nearest_stores/​opening_hours:​days/​open/​begin string Time the store opens. Stores may open multiple times a day, so the 'open' array can contain multiple elements.
Pattern: ^[0-9]{2}:[0-9]{2}$
"example"
nearest_stores/​opening_hours:​days/​open/​end string Time the store closes.
Pattern: ^[0-9]{2}:[0-9]{2}$
"example"
nearest_stores/​title string The store's name.
Length: 1..120
"example"
reference_key nullable string A key referencing an order or another internal process.
Pattern: ^[a-zA-Z0-9!"#\$%&'()*+,-\./:;<=>\?@\[\\\]\^_\{\|\}~]+$
Length: 0..40
"O64737X"
refund:​for_slip_id string For refunds, references a payment slip's id. See 'Refund Slips' above.
Length: 1..50
"slp-d90ab05c-69f2-4e87-9972-97b3275a0ccd"
slip_type string Slip type, see above.
One of: "payment" or "payout" or "refund"
"payment"
transactions/​amount string Amount with a dot as decimal separator and maximum of two decimal places. Negative when paying out money.
Pattern: ^-?[0-9]+\.[0-9]+$
"123.34"
transactions/​country nullable string Country in which a transaction was scanned and paid as two-letter ISO 3166-1 alpha 2 language code.
Length: 2
"DE"
transactions/​currency string Currency as three-letter ISO 4217 code.
Length: 3
"EUR"
transactions/​displayed_due_at date-time Time defining the expected time until which the transaction should be paid. Format is date-time as defined in RFC 3339 Section 5.6. "2015-01-01T12:00:00Z"
transactions/​id string A string identifying a transaction. As with all values in this API returned as string, if you need to store this, make sure to store it as a string.
Length: 1..50
"4729294329"
transactions/​paid_at_store:​address:​city string The store's city. This field is not returned by default. See Optional Features for more information.
Length: 1..255
"Berlin"
transactions/​paid_at_store:​address:​country string The store's country, a ISO 3166-1 alpha 2 language code. This field is not returned by default. See Optional Features for more information.
Pattern: ^[A-Z]+$
Length: 0..2
"DE"
transactions/​paid_at_store:​address:​street_and_no string The store's street and house number. This field is not returned by default. See Optional Features for more information.
Length: 0..255
"Budapester Str. 50"
transactions/​paid_at_store:​address:​zipcode string The store's zip code. This field is not returned by default. See Optional Features for more information.
Length: 0..10
"10787"
transactions/​paid_at_store:​coordinates:​lat string The store's latitude represented as a string (between -90.0 and 90.0). This field is not returned by default. See Optional Features for more information.
Pattern: ^-?[0-9]+\.[0-9]+$
"52.4867530074"
transactions/​paid_at_store:​coordinates:​lng string The store's longitude represented as a string (between -180.0 and 180.0). This field is not returned by default. See Optional Features for more information.
Pattern: ^-?[0-9]+\.[0-9]+$
"13.3587746557"
transactions/​paid_at_store:​title string The store's name. This field is not returned by default. See Optional Features for more information.
Length: 1..120
"example"
transactions/​state string A transaction's state. Only pending transactions can be modified.
One of: "pending" or "locked" or "paid" or "expired" or "invalidated" or "declined"
"pending"

Download JSON schema

Headers

Header Description
Authorization A per-request signature for authentication, see Authentication.

URL Parameters

Parameter Description Format
id A slip's id. String

Errors

General API Errors can also be returned by this resource. See also Errors.

Status Class Code and hints
404 invalid_state slip_not_found

Update Slip

PATCH /slips/{id}

Change certain slip attributes. Only slips with a pending transaction can be updated. We notify the customer about certain changes.

When one of the following values is changed, we send an email to the customer:

When customer:cell_phone is changed for a payment or partial payment slip, we send a text message to the new recipient. We do not send text messages for payout and refund slips.

For payments, the following attributes can be changed:

For partial payments, the following attributes can be changed:

For payouts, the following attributes can be changed:

For refunds, the following attribute can be changed:

None of the fields are required. If a field is provided, the API tries to update it. Do not pass null for fields you do not want to change, that would mean setting the field to null (which is not possible for most fields).

For any field, passing the value that is already set is not treated as a change by the API. E.g. setting the same customer email the slip already has does not result in an additional email being sent.

We generally discourage changing the amount after the user has received an email or text message due to a poor user experience: The amount shown in a user's PDF slip or text message can differ from the amount shown by the cash register, which might be unexpected for the customer. If you need to update the amount after creating a slip, we recommend creating the slip without email and cell_phone number and setting them later, together with the amount.

Example Request Body

{
  "customer": {
    "email": "john@example.com",
    "cell_phone": "+495423112345"
  },
  "expires_at": "2016-01-10T12:34:56Z",
  "transactions": [
    {
      "id": "4729294329",
      "amount": "150.00",
      "displayed_due_at": "2020-06-12T07:32:19Z"
    }
  ],
  "reference_key": "NEWKEY"
}

Request Attributes

Name Type Description Example
customer:​cell_phone nullable string The customer's cell phone number in international format. If set to a non-null value, can not be reset to null.
Pattern: ^\+[0-9]+$
Length: 9..19
"+49151123456789"
customer:​email nullable idn-email The customer's email address. If set to a non-null value, cannot be reset to null.
Length: 3..80
"john@example.com"
expires_at date-time Time the slip expires and can no longer be used. Not possible for partial_payments. Format is date-time as defined in RFC 3339 Section 5.6.
Pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(|\.[0-9]+)(Z|[\+-][0-9]{2}:[0-9]{2})$
"2015-01-01T12:00:00Z"
reference_key nullable string A key referencing an order or another internal process. Can only be changed if it was not set previously, so if the previous value is null.
Pattern: ^[a-zA-Z0-9!"#\$%&'()*+,-\./:;<=>\?@\[\\\]\^_\{\|\}~]+$
Length: 0..40
"O64737X"
transactions/​amount string Amount to be paid in/out with a dot as decimal separator and maximum of two decimal places. We discourage changing the amount after the user has received the slip, see above.
Pattern: ^-?[0-9]+\.[0-9]+$
"81.32"
transactions/​id string The id of the transaction to be changed. Note that this is not the slip id. "4729294329"

Download JSON schema

Example Response Body for HTTP status 200 with Content-Type application/json

{
  "id": "slp-d90ab05c-69f2-4e87-9972-97b3275a0ccd",
  "slip_type": "payment",
  "division_id": "1234",
  "reference_key": "O64737X",
  "hook_url": "https://psp.example.com/hook",
  "expires_at": "2016-01-10T12:34:56Z",
  "customer": {
    "key": "LDFKHSLFDHFL",
    "cell_phone_last_4_digits": "6789",
    "email": "john@example.com",
    "language": "de-DE"
  },
  "metadata": {
    "order_id": "1234",
    "invoice_no": "A123"
  },
  "transactions": [
    {
      "id": "4729294329",
      "currency": "EUR",
      "amount": "123.34",
      "displayed_due_at": "2020-06-12T07:32:19Z",
      "state": "pending",
      "country": "DE"
    }
  ],
  "nearest_stores": [
    {
      "title": "mobilcom-debitel",
      "logo": {
        "id": "17077"
      },
      "distance_m": 1160,
      "address": {
        "city": "Berlin",
        "country": "DE",
        "street_and_no": "Grunerstraße 20",
        "zipcode": "10179"
      },
      "opening_hours": {
        "days": [
          { "day": "sun", "open": [] },
          { "day": "mon", "open": [{"begin": "10:00", "end": "21:00"}] },
          { "day": "tue", "open": [{"begin": "10:00", "end": "21:00"}] },
          { "day": "wed", "open": [{"begin": "10:00", "end": "21:00"}] },
          { "day": "thu", "open": [{"begin": "10:00", "end": "21:00"}] },
          { "day": "fri", "open": [{"begin": "10:00", "end": "21:00"}] },
          { "day": "sat", "open": [{"begin": "10:00", "end": "21:00"}] }
        ]
      }
    },
    {
      "title": "dm-drogerie markt",
      "logo": {
        "id": "13045"
      },
      "distance_m": 1220,
      "address": {
        "city": "Berlin",
        "country": "DE",
        "street_and_no": "Alexanderplatz 1",
        "zipcode": "10178"
      },
      "opening_hours": {
        "days": [
          { "day": "sun", "open": [] },
          { "day": "mon", "open": [{"begin": "09:00", "end": "22:00"}] },
          { "day": "tue", "open": [{"begin": "09:00", "end": "22:00"}] },
          { "day": "wed", "open": [{"begin": "09:00", "end": "22:00"}] },
          { "day": "thu", "open": [{"begin": "09:00", "end": "22:00"}] },
          { "day": "fri", "open": [{"begin": "09:00", "end": "22:00"}] },
          { "day": "sat", "open": [{"begin": "09:00", "end": "22:00"}] }
        ]
      }
    },
    {
      "title": "dm-drogerie markt",
      "logo": {
        "id": "13045"
      },
      "distance_m": 1280,
      "address": {
        "city": "Berlin",
        "country": "DE",
        "street_and_no": "Henriette-Herz-Platz 4",
        "zipcode": "10178"
      },
      "opening_hours": {
        "days": [
          { "day": "sun", "open": [] },
          { "day": "mon", "open": [{"begin": "08:30", "end": "21:00"}] },
          { "day": "tue", "open": [{"begin": "08:30", "end": "21:00"}] },
          { "day": "wed", "open": [{"begin": "08:30", "end": "21:00"}] },
          { "day": "thu", "open": [{"begin": "08:30", "end": "21:00"}] },
          { "day": "fri", "open": [{"begin": "08:30", "end": "21:00"}] },
          { "day": "sat", "open": [{"begin": "09:00", "end": "21:00"}] }
        ]
      }
    }
  ]
}

Response Attributes

Name Type Description Example
barcode_code128 string This number represents the barcode the customer gives to a cashier in a store. This field is not returned by default. See Optional Features for more information.
Pattern: ^[0-9]{13,40}$
Length: 13..40
"4051234567890"
barcode_ean13 string This number represents the barcode the customer gives to a cashier in a store. This field is not returned by default. See Optional Features for more information.
Pattern: ^[0-9]{13}$
Length: 13
"4051234567890"
customer:​cell_phone_last_4_digits nullable string Last 4 digits of the customer's cell phone number (cut off for privacy reasons)
Pattern: ^[0-9]*$
Length: 4
"6789"
customer:​email nullable string The customer's email address.
Length: 3..88
"john@example.com"
customer:​key string A key uniquely identifying the customer. See Identifying a customer for more information.
Pattern: ^[a-zA-Z0-9!"#\$%&'()*+,-\./:;<=>\?@\[\\\]\^_\{\|\}~]+$
Length: 0..40
"LDFKHSLFDHFL"
customer:​language string The language used for communicating with the customer (e.g. for email, text message, web interface) (RFC 5646 language-region code).
Pattern: ^[a-z]{2}-[A-Z]{2}$
"de-DE"
division_id string A string identifying the division that created the slip. A division can only access their own slips, so this is always the same per API key.
Length: 1..50
"1234"
expires_at date-time Time the slip expires and can no longer be used. Format is date-time as defined in RFC 3339 Section 5.6. "2015-01-01T12:00:00Z"
hook_url nullable string Per-slip webhook URL to use instead of the one configured in the viafintech App. See Webhooks. null
id string A string identifying a slip.
Length: 1..50
"slp-d90ab05c-69f2-4e87-9972-97b3275a0ccd"
metadata object Custom metadata not processed by viafintech, useful for associating slips with internal identifiers. Keys and values are strings.
nearest_stores/​address:​city string The store's city.
Length: 1..255
"Berlin"
nearest_stores/​address:​country string The store's country, a ISO 3166-1 alpha 2 language code.
Pattern: ^[A-Z]+$
Length: 0..2
"DE"
nearest_stores/​address:​street_and_no string The store's street and house number.
Length: 0..255
"Budapester Str. 50"
nearest_stores/​address:​zipcode string The store's zip code.
Length: 0..10
"10787"
nearest_stores/​distance_m integer Distance in meters from the given address to the store. Note that for refunds, we currently ignore the address given when creating the refund and use the address given when creating the original payment. 42
nearest_stores/​logo:​id string A unique identifier for a logo related to the store. Please contact us if you want to use store logos.
Length: 1..50
"example"
nearest_stores/​opening_hours:​days/​day string The day of week the opening hours are valid for. Note that the JSON objects describing the different weekdays are always ordered, beginning with Sunday. You do not necessarily have to evaluate this field, but can assume that the first object in the 'days' array refers to Sunday, the second to Monday, and so on.
One of: "sun" or "mon" or "tue" or "wed" or "thu" or "fri" or "sat"
"sun"
nearest_stores/​opening_hours:​days/​open/​begin string Time the store opens. Stores may open multiple times a day, so the 'open' array can contain multiple elements.
Pattern: ^[0-9]{2}:[0-9]{2}$
"example"
nearest_stores/​opening_hours:​days/​open/​end string Time the store closes.
Pattern: ^[0-9]{2}:[0-9]{2}$
"example"
nearest_stores/​title string The store's name.
Length: 1..120
"example"
reference_key nullable string A key referencing an order or another internal process.
Pattern: ^[a-zA-Z0-9!"#\$%&'()*+,-\./:;<=>\?@\[\\\]\^_\{\|\}~]+$
Length: 0..40
"O64737X"
refund:​for_slip_id string For refunds, references a payment slip's id. See 'Refund Slips' above.
Length: 1..50
"slp-d90ab05c-69f2-4e87-9972-97b3275a0ccd"
slip_type string Slip type, see above.
One of: "payment" or "payout" or "refund"
"payment"
transactions/​amount string Amount with a dot as decimal separator and maximum of two decimal places. Negative when paying out money.
Pattern: ^-?[0-9]+\.[0-9]+$
"123.34"
transactions/​country nullable string Country in which a transaction was scanned and paid as two-letter ISO 3166-1 alpha 2 language code.
Length: 2
"DE"
transactions/​currency string Currency as three-letter ISO 4217 code.
Length: 3
"EUR"
transactions/​displayed_due_at date-time Time defining the expected time until which the transaction should be paid. Format is date-time as defined in RFC 3339 Section 5.6. "2015-01-01T12:00:00Z"
transactions/​id string A string identifying a transaction. As with all values in this API returned as string, if you need to store this, make sure to store it as a string.
Length: 1..50
"4729294329"
transactions/​paid_at_store:​address:​city string The store's city. This field is not returned by default. See Optional Features for more information.
Length: 1..255
"Berlin"
transactions/​paid_at_store:​address:​country string The store's country, a ISO 3166-1 alpha 2 language code. This field is not returned by default. See Optional Features for more information.
Pattern: ^[A-Z]+$
Length: 0..2
"DE"
transactions/​paid_at_store:​address:​street_and_no string The store's street and house number. This field is not returned by default. See Optional Features for more information.
Length: 0..255
"Budapester Str. 50"
transactions/​paid_at_store:​address:​zipcode string The store's zip code. This field is not returned by default. See Optional Features for more information.
Length: 0..10
"10787"
transactions/​paid_at_store:​coordinates:​lat string The store's latitude represented as a string (between -90.0 and 90.0). This field is not returned by default. See Optional Features for more information.
Pattern: ^-?[0-9]+\.[0-9]+$
"52.4867530074"
transactions/​paid_at_store:​coordinates:​lng string The store's longitude represented as a string (between -180.0 and 180.0). This field is not returned by default. See Optional Features for more information.
Pattern: ^-?[0-9]+\.[0-9]+$
"13.3587746557"
transactions/​paid_at_store:​title string The store's name. This field is not returned by default. See Optional Features for more information.
Length: 1..120
"example"
transactions/​state string A transaction's state. Only pending transactions can be modified.
One of: "pending" or "locked" or "paid" or "expired" or "invalidated" or "declined"
"pending"

Download JSON schema

Headers

Header Description
Authorization A per-request signature for authentication, see Authentication.

URL Parameters

Parameter Description Format
id A slip's id. String

Errors

General API Errors can also be returned by this resource. See also Errors.

Status Class Code and hints
415 invalid_format request_body_not_valid_json
400 invalid_format unknown_additional_parameter
404 invalid_state slip_not_found
400 invalid_state slip_invalidated
400 invalid_state slip_declined
400 invalid_state slip_expired
400 invalid_state slip_locked - Slip has been scanned in a store and not yet been paid.
400 invalid_state slip_paid
400 invalid_state customer_cell_phone_cannot_be_removed - A previously set customer phone number cannot be removed, only changed.
400 invalid_state customer_email_cannot_be_removed - A previously set customer email cannot be removed, only changed.
400 invalid_state reference_key_already_set - The slip already has a reference key set.
400 invalid_state reference_key_already_exists - Your division is configured to not allow duplicate reference keys.
400 invalid_state transaction_not_found
400 invalid_parameter request_body_not_a_json_object
400 invalid_parameter expires_at_not_settable - Only for partial_payments
400 invalid_parameter customer_cell_phone_not_settable
400 invalid_parameter customer_email_not_settable
400 invalid_parameter reference_key_not_settable
400 invalid_parameter transactions_amount_not_settable
400 invalid_parameter invalid_expires_at
400 invalid_parameter invalid_customer
400 invalid_parameter invalid_customer_cell_phone
400 invalid_parameter invalid_customer_email
400 invalid_parameter invalid_reference_key
400 invalid_parameter invalid_transactions
400 invalid_parameter invalid_transactions_id
400 invalid_parameter invalid_transactions_amount
400 invalid_parameter too_early_expires_at
400 invalid_parameter too_late_expires_at
400 invalid_parameter transactions_not_changeable
403 not_allowed legal_amount_limit_exceeded - For legal reasons, we are only allowed to process a certain amount per time.
403 not_allowed slip_text_message_resend_limit_exceeded

Retrieve Slip PDF

GET /slips/{id}/media/pdf

Retrieve the slip's PDF representation for printing.

The customer usually receives the slip PDF via email or can access it via the checkout, so in most cases it is not necessary to download the PDF. In some cases this endpoint can be useful, for example if you want to print the PDF yourself send a letter to the customer.

Downloading the PDF is only possible for slips in the pending state.

Note: Due to security reasons this endpoint is disabled by default and can only be enabled by viafintech. Please feel free to contact us if you are interested in using this feature.

HTTP Status 200 with Content-Type application/pdf

Headers

Header Description
Authorization A per-request signature for authentication, see Authentication.

URL Parameters

Parameter Description Format
id A slip's id. String

Errors

General API Errors can also be returned by this resource. See also Errors.

Status Class Code and hints
404 invalid_state slip_not_found
400 invalid_state slip_invalidated
400 invalid_state slip_declined
400 invalid_state slip_expired
400 invalid_state slip_paid
403 not_allowed slip_media_download_not_allowed - See Retrieve Slip PDF.

Resend Email / Text Message

POST /slips/{id}/resend/{message_type}

Resend the email or text message containing slip information like the barcode to the customer. Only possible for slips with a pending transaction. Text messages can only be sent for payment and partial payment slips and not for payout and refund slips.

Text messages can only be resent twice. After that, an attempt to resend a text message will return an error. Resending a text message by changing the customer:cell_phone number via PATCH also counts as a resend and is no longer possible when the limit has been reached.

Note that the sandbox API endpoint does not send text messages.

This endpoint returns an empty JSON object as response.

Example Response Body for HTTP status 202 with Content-Type application/json

{}

Headers

Header Description
Authorization A per-request signature for authentication, see Authentication.

URL Parameters

Parameter Description Format
id A slip's id. String
message_type String, one of (email,text_message)

Errors

General API Errors can also be returned by this resource. See also Errors.

Status Class Code and hints
404 invalid_state slip_not_found
400 invalid_state slip_invalidated
400 invalid_state slip_declined
400 invalid_state slip_expired
400 invalid_state slip_paid
400 invalid_state slip_does_not_have_customer_cell_phone
400 invalid_state slip_does_not_have_customer_email
403 not_allowed slip_text_message_resend_limit_exceeded

Invalidate Slip

POST /slips/{id}/invalidate

Invalidate a slip so it can no longer be used. Only possible for slips with a pending transaction, so e.g. paid slips can not be invalidated. For partial payment slips it is possible to invalidate all the still pending transactions.

This action is final and can not be undone. An invalid slip can no longer be updated or resent via the API or paid by the customer.

When the slip contains a customer:email, we notify the customer via email that the slip is no longer valid.

Invalidating an already invalidated slip does nothing and returns the slip as if it had not been invalidated before.

Example Response Body for HTTP status 200 with Content-Type application/json

{
  "id": "slp-d90ab05c-69f2-4e87-9972-97b3275a0ccd",
  "slip_type": "payment",
  "division_id": "1234",
  "reference_key": "O64737X",
  "hook_url": "https://psp.example.com/hook",
  "expires_at": "2016-01-10T12:34:56Z",
  "customer": {
    "key": "LDFKHSLFDHFL",
    "cell_phone_last_4_digits": "6789",
    "email": "john@example.com",
    "language": "de-DE"
  },
  "metadata": {
    "order_id": "1234",
    "invoice_no": "A123"
  },
  "transactions": [
    {
      "id": "4729294329",
      "currency": "EUR",
      "amount": "123.34",
      "displayed_due_at": "2020-06-12T07:32:19Z",
      "state": "pending",
      "country": "DE"
    }
  ],
  "nearest_stores": [
    {
      "title": "mobilcom-debitel",
      "logo": {
        "id": "17077"
      },
      "distance_m": 1160,
      "address": {
        "city": "Berlin",
        "country": "DE",
        "street_and_no": "Grunerstraße 20",
        "zipcode": "10179"
      },
      "opening_hours": {
        "days": [
          { "day": "sun", "open": [] },
          { "day": "mon", "open": [{"begin": "10:00", "end": "21:00"}] },
          { "day": "tue", "open": [{"begin": "10:00", "end": "21:00"}] },
          { "day": "wed", "open": [{"begin": "10:00", "end": "21:00"}] },
          { "day": "thu", "open": [{"begin": "10:00", "end": "21:00"}] },
          { "day": "fri", "open": [{"begin": "10:00", "end": "21:00"}] },
          { "day": "sat", "open": [{"begin": "10:00", "end": "21:00"}] }
        ]
      }
    },
    {
      "title": "dm-drogerie markt",
      "logo": {
        "id": "13045"
      },
      "distance_m": 1220,
      "address": {
        "city": "Berlin",
        "country": "DE",
        "street_and_no": "Alexanderplatz 1",
        "zipcode": "10178"
      },
      "opening_hours": {
        "days": [
          { "day": "sun", "open": [] },
          { "day": "mon", "open": [{"begin": "09:00", "end": "22:00"}] },
          { "day": "tue", "open": [{"begin": "09:00", "end": "22:00"}] },
          { "day": "wed", "open": [{"begin": "09:00", "end": "22:00"}] },
          { "day": "thu", "open": [{"begin": "09:00", "end": "22:00"}] },
          { "day": "fri", "open": [{"begin": "09:00", "end": "22:00"}] },
          { "day": "sat", "open": [{"begin": "09:00", "end": "22:00"}] }
        ]
      }
    },
    {
      "title": "dm-drogerie markt",
      "logo": {
        "id": "13045"
      },
      "distance_m": 1280,
      "address": {
        "city": "Berlin",
        "country": "DE",
        "street_and_no": "Henriette-Herz-Platz 4",
        "zipcode": "10178"
      },
      "opening_hours": {
        "days": [
          { "day": "sun", "open": [] },
          { "day": "mon", "open": [{"begin": "08:30", "end": "21:00"}] },
          { "day": "tue", "open": [{"begin": "08:30", "end": "21:00"}] },
          { "day": "wed", "open": [{"begin": "08:30", "end": "21:00"}] },
          { "day": "thu", "open": [{"begin": "08:30", "end": "21:00"}] },
          { "day": "fri", "open": [{"begin": "08:30", "end": "21:00"}] },
          { "day": "sat", "open": [{"begin": "09:00", "end": "21:00"}] }
        ]
      }
    }
  ]
}

Response Attributes

Name Type Description Example
barcode_code128 string This number represents the barcode the customer gives to a cashier in a store. This field is not returned by default. See Optional Features for more information.
Pattern: ^[0-9]{13,40}$
Length: 13..40
"4051234567890"
barcode_ean13 string This number represents the barcode the customer gives to a cashier in a store. This field is not returned by default. See Optional Features for more information.
Pattern: ^[0-9]{13}$
Length: 13
"4051234567890"
customer:​cell_phone_last_4_digits nullable string Last 4 digits of the customer's cell phone number (cut off for privacy reasons)
Pattern: ^[0-9]*$
Length: 4
"6789"
customer:​email nullable string The customer's email address.
Length: 3..88
"john@example.com"
customer:​key string A key uniquely identifying the customer. See Identifying a customer for more information.
Pattern: ^[a-zA-Z0-9!"#\$%&'()*+,-\./:;<=>\?@\[\\\]\^_\{\|\}~]+$
Length: 0..40
"LDFKHSLFDHFL"
customer:​language string The language used for communicating with the customer (e.g. for email, text message, web interface) (RFC 5646 language-region code).
Pattern: ^[a-z]{2}-[A-Z]{2}$
"de-DE"
division_id string A string identifying the division that created the slip. A division can only access their own slips, so this is always the same per API key.
Length: 1..50
"1234"
expires_at date-time Time the slip expires and can no longer be used. Format is date-time as defined in RFC 3339 Section 5.6. "2015-01-01T12:00:00Z"
hook_url nullable string Per-slip webhook URL to use instead of the one configured in the viafintech App. See Webhooks. null
id string A string identifying a slip.
Length: 1..50
"slp-d90ab05c-69f2-4e87-9972-97b3275a0ccd"
metadata object Custom metadata not processed by viafintech, useful for associating slips with internal identifiers. Keys and values are strings.
nearest_stores/​address:​city string The store's city.
Length: 1..255
"Berlin"
nearest_stores/​address:​country string The store's country, a ISO 3166-1 alpha 2 language code.
Pattern: ^[A-Z]+$
Length: 0..2
"DE"
nearest_stores/​address:​street_and_no string The store's street and house number.
Length: 0..255
"Budapester Str. 50"
nearest_stores/​address:​zipcode string The store's zip code.
Length: 0..10
"10787"
nearest_stores/​distance_m integer Distance in meters from the given address to the store. Note that for refunds, we currently ignore the address given when creating the refund and use the address given when creating the original payment. 42
nearest_stores/​logo:​id string A unique identifier for a logo related to the store. Please contact us if you want to use store logos.
Length: 1..50
"example"
nearest_stores/​opening_hours:​days/​day string The day of week the opening hours are valid for. Note that the JSON objects describing the different weekdays are always ordered, beginning with Sunday. You do not necessarily have to evaluate this field, but can assume that the first object in the 'days' array refers to Sunday, the second to Monday, and so on.
One of: "sun" or "mon" or "tue" or "wed" or "thu" or "fri" or "sat"
"sun"
nearest_stores/​opening_hours:​days/​open/​begin string Time the store opens. Stores may open multiple times a day, so the 'open' array can contain multiple elements.
Pattern: ^[0-9]{2}:[0-9]{2}$
"example"
nearest_stores/​opening_hours:​days/​open/​end string Time the store closes.
Pattern: ^[0-9]{2}:[0-9]{2}$
"example"
nearest_stores/​title string The store's name.
Length: 1..120
"example"
reference_key nullable string A key referencing an order or another internal process.
Pattern: ^[a-zA-Z0-9!"#\$%&'()*+,-\./:;<=>\?@\[\\\]\^_\{\|\}~]+$
Length: 0..40
"O64737X"
refund:​for_slip_id string For refunds, references a payment slip's id. See 'Refund Slips' above.
Length: 1..50
"slp-d90ab05c-69f2-4e87-9972-97b3275a0ccd"
slip_type string Slip type, see above.
One of: "payment" or "payout" or "refund"
"payment"
transactions/​amount string Amount with a dot as decimal separator and maximum of two decimal places. Negative when paying out money.
Pattern: ^-?[0-9]+\.[0-9]+$
"123.34"
transactions/​country nullable string Country in which a transaction was scanned and paid as two-letter ISO 3166-1 alpha 2 language code.
Length: 2
"DE"
transactions/​currency string Currency as three-letter ISO 4217 code.
Length: 3
"EUR"
transactions/​displayed_due_at date-time Time defining the expected time until which the transaction should be paid. Format is date-time as defined in RFC 3339 Section 5.6. "2015-01-01T12:00:00Z"
transactions/​id string A string identifying a transaction. As with all values in this API returned as string, if you need to store this, make sure to store it as a string.
Length: 1..50
"4729294329"
transactions/​paid_at_store:​address:​city string The store's city. This field is not returned by default. See Optional Features for more information.
Length: 1..255
"Berlin"
transactions/​paid_at_store:​address:​country string The store's country, a ISO 3166-1 alpha 2 language code. This field is not returned by default. See Optional Features for more information.
Pattern: ^[A-Z]+$
Length: 0..2
"DE"
transactions/​paid_at_store:​address:​street_and_no string The store's street and house number. This field is not returned by default. See Optional Features for more information.
Length: 0..255
"Budapester Str. 50"
transactions/​paid_at_store:​address:​zipcode string The store's zip code. This field is not returned by default. See Optional Features for more information.
Length: 0..10
"10787"
transactions/​paid_at_store:​coordinates:​lat string The store's latitude represented as a string (between -90.0 and 90.0). This field is not returned by default. See Optional Features for more information.
Pattern: ^-?[0-9]+\.[0-9]+$
"52.4867530074"
transactions/​paid_at_store:​coordinates:​lng string The store's longitude represented as a string (between -180.0 and 180.0). This field is not returned by default. See Optional Features for more information.
Pattern: ^-?[0-9]+\.[0-9]+$
"13.3587746557"
transactions/​paid_at_store:​title string The store's name. This field is not returned by default. See Optional Features for more information.
Length: 1..120
"example"
transactions/​state string A transaction's state. Only pending transactions can be modified.
One of: "pending" or "locked" or "paid" or "expired" or "invalidated" or "declined"
"pending"

Download JSON schema

Headers

Header Description
Authorization A per-request signature for authentication, see Authentication.

URL Parameters

Parameter Description Format
id A slip's id. String

Errors

General API Errors can also be returned by this resource. See also Errors.

Status Class Code and hints
404 invalid_state slip_not_found
400 invalid_state slip_declined
400 invalid_state slip_expired
400 invalid_state slip_locked - Slip has been scanned in a store and not yet been paid.
400 invalid_state slip_paid