Background

In November 2024, secupay AG obtained principal membership for Visa and Mastercard for credit card acquiring services. This enables us to offer our customers services that are better tailored to their needs. In order to benefit from the changes, the service must be converted to the new acquiring model and, depending on the scope of functions, the technical connection must also be adapted. We will involve you in this process in good time and to the extent necessary.

The following is only relevant for credit card payments.

Demo Transactions

Beginning with secupay Acquiring, demo mode transactions are no longer available at the live system.

Currently you can create both, demo and live transactions, on both environments, sandbox and live. In future, there will be no demo transaction mode, but only sandbox and live environments.

Dynamic Descriptors

The following would have no effect when applied to subscription payments.

Dynamic descriptors can be used to pass a DBA (“doing business as”) name and local address instead of the legal name and registration address. A DBA can be a trademark or store name that is better understandable by the card holders when checking their card or bank statements, and can lead to fewer chargebacks. This works only with credit card payment together with the new acquiring by secupay.

Please note that you must only use DBA names and addresses to which you have a legitimate claim.

The dynamic descriptor can be passed when creating the Smart Transaction that is used to control the checkout process. It needs to be inserted in the payment context of the Smart Transaction details:

Excerpt from Request Body
POST /api/v2/Smart/Transactions HTTP/1.1
Host: connect-testing.secuconnect.com
...
 
{
// ...
"payment_context": {
// ...
"dynamic_descriptor": {
"merchant_name": "ACME Buero-Paradies",
"merchant_city": "Bielefeld"
}
}
}

Recurring Payment

To use a credit card for recurring payments, you must:

  • Make the first payment with a Customer Initiated Transaction (CIT). You must also request a Network Token, and record both Payment Container ID (PCT_…) and Payment Transaction ID (PCI_…).
  • Make the subsequent payments as Merchant Initiated Transactions (MIT). You must also pass the recorded IDs at different stages of the process.

Subsequent Payments can be captured without customer interaction. The Strong Customer Authentication (SCA) by the Revised Payment Services Directive (PSD2) is not needed.

Your contract needs to be activated for recurring payments. Otherwise the subsequent payment with MIT cannot be authorised.

There are these two cases:

  • Scheduled: A series of recurring payments with a fixed amount and frequency, such as a subscription service.
  • Unscheduled: A series of irregular transactions using stored card details, such as an automatic account top-up or a rideshare fee. Often this is referred to as Unscheduled Card On File, or for short UCOF.

For the API integration, this makes only a difference for the first payment.

To make recurring payments with direct debit, you will still only need to record the Payment Container ID and pass it back later.

In connection with the migration to the new acquiring system, this means:

  • No changes to implementations used simultaneously for SEPA direct debits
  • When the Smart Transaction is created for credit card payments, the additional parameters change; like before these are different between the first payment and subsequent payments
  • In addition to the Payment Container ID (PCT_…), also the Payment Transaction ID from first payment must be recorded now; it must be passed when creating the Smart Transactions for subsequent payments
  • For a more reliable solution than before, status changes of the Payment Container can be subscribed now

The following examples consider only credit card payment. The examples at Recurring Payments show the resulting calls in full detail.

Create the Smart Transaction for the Initial Payment

When you make the first payment, you must add the needed "mit_instructions" to the "payment_context" when you create the Smart Transaction:

First an example for unscheduled recurring payments:

Request (Unscheduled)
POST /api/v2/Smart/Transactions HTTP/1.1
Host: connect-testing.secuconnect.com
Authorization: Bearer qb56tjj1bcvo9n2nj4u38k84lo
Content-Type: application/json
Accept: application/json
 
{
// ...
"payment_context":
{
// ...
"mit_instructions":
{
"type": "cit",
"standing_instruction": "ucof"
},
"container_instructions":
{
"request_token": true,
"notification_url": "https://shop.example.com/network-token/update"
}
    }
}

Now the same example with only the necessary or changed fields for scheduled recurring payments:

Request (Scheduled)
POST /api/v2/Smart/Transactions HTTP/1.1
Host: connect-testing.secuconnect.com
Authorization: Bearer qb56tjj1bcvo9n2nj4u38k84lo
Content-Type: application/json
Accept: application/json
 
{
// ...
"payment_context":
{
// ...
"mit_instructions":
{
"type": "cit",
"standing_instruction": "recurring",
"recurring_expiry": "2029-07-31",
"recurring_frequency": "30"
},
"container_instructions":
{
"request_token": true,
"notification_url": "https://shop.example.com/network-token/update"
}
    }
}

If everything is fine, the API responds with 200 OK and the created Smart Transaction.

Details of the related fields:

Field

Type

Meaning

mit_instructions

object

Instructions for MIT transactions needed when making the payment in the next step.

container_instructions

object

Instructions considered when creating the Payment Container in the next step.

Details of "mit_instructions":

Field

Type

Meaning

type

string

Marks a transaction as the Customer-Initiated Transaction ("cit") to be referred later to, or as one of the relating Merchant-Initiated Transactions ("mit")

standing_instruction

string

Tells whether there is a fix or flexible standing transaction:

  • "recuring" for scheduled payments
  • "ucof" for Unscheduled Card On File (UCOF)

recurring_expiry

string

ISO-8601 date; expiry date for the card

Note: Please consider more reasons for it to become invalidated

recurring_frequency

string

Frequency of the subsequent payments in days

Details of "container_instructions":

Field

Type

Meaning

request_token

boolean

Requests to save the credit card reference securely on the servers of a credit card network like VISA or MasterCard (“Network Token“)

notification_url

string

Callback URL on your server for status updates for the Payment Container related to the Network Token

Authorise and Capture the Initial Payment (Custom Checkout)

The following description is only useful for custom checkout implementations. Smart Checkout abstracts the complexity of payment method selection and prompting data from you. You would catch the Payment Container ID either at the success URL or when your system receives the status notification for the payment container. (See below.)

Imagine you have authorised the Smart Transaction for the first order by using this call, for example:

Request
POST /api/v2/Smart/Transactions/STX_3Z8EUQX0A2PBHRJV9FRY7P56GEDZAK/prepare/creditcard HTTP/1.1
Host: connect-testing.secuconnect.com
Authorization: Bearer qb56tjj1bcvo9n2nj4u38k84lo
Content-Type: application/json
Accept: application/json
 
{
"container": {
"type": "credit_card",
"private": {
"owner": "Max Mustermann",
"pan": "463544XXXXXX2298",
"expiration_date": "2034-02-01T00:00:00+00:00",
"issuer": "VISA",
"transact_container": "MzkzOTQ0MGI1YTBmMDg2ZDkxYTEwNzIyZTMwNTgwNGZjYTU3...",
"transact_skey_pubkey": "8ebccbb725d89d6286f227e672f24155e8b50b9688e7a45b...",
"transact_skey_keyname": "spp_2025.pem",
"transact_hash": "671439c1a91466df0249d8ab1b3595b682def08b1aea05a2d66e6adcf3d37a98"
}
},
"callback_urls": {
"success_url": "https://shop.example.com/payment/success?nonce=ciix8j3qbqffg8dcdc7b",
"failure_url": "https://shop.example.com/payment/failure?nonce=ciix8j3qbqffg8dcdc7b"
}
}

If everything was fine, the API would have responded with something with 200 OK and the updated Smart Transaction:

Response
HTTP/1.1 200 OK
Content-Type: application/json
 
{
"object": "smart.transactions",
"id": "STX_3Z8EUQX0A2PBHRJV9FRY7P56GEDZAK",
// ...
"container": {
"object": "payment.containers",
"id": "PCT_3JU4VGYZF2XY8EJHH9FQ7WGYNZGJA4",
"type": "credit_card"
// ...
"token_status": {
"status": "requested",
// ...
}
    },
"transactions": [
{
"object": "payment.transactions",
"id": "PCI_W026W643US3TWCGZA0AVZ248W8TSMW",
"trans_id": 123456789,
"transaction_hash": "abcdefghijkl12345678"
}
],
"created": "2025-02-25T15:55:58+01:00",
"updated": "2025-02-25T15:56:16+01:00",
"status": "created",
// ...
"payment_method": "creditcard",
"trans_id": 123456789,
"iframe_url": "https://connect-testing.secuconnect.com/spp/challenge/?token=5ab8b08...",
// ...
}

For direct debit it would look similar but there is no 3-D Secure, and thus no iframe_url. Credit card payments require a 3-D Secure check if not exempted. So the iframe_url may be present or not. If auto_capture is set, the payment would be captured immediately after successful authorisation.

Existing implementations need to save the Payment Container ID (container.id). Now you also need the Payment Transaction ID (transactions[0].id). It is passed when creating the Smart Transactions for subsequent payments.

You would also need to manage the life cycle of the Payment Container ID.

Handle Failed Token Request upon Initial Payment

When you authorise (and perhaps auto-capture) the first payment, the payment may succeed whilst the Network Token request would fail. In this case the Payment Container details would be useless, and standing order or subscription would not work.

Please take these considerations into account:

  • The Network Token creation might fail from the beginning
  • The Network Token might be invalidated later for a number of reasons (token expiry, card not renewed, etc.)

You must handle this situation.

One way to split the initial payment, or that for a token renewal, from the order, is to make a credit card authorisation with an amount of zero.

Imagine this authorisation request:

Request
POST /api/v2/Smart/Transactions/STX_3Z8EUQX0A2PBHRJV9FRY7P56GEDZAK/prepare/creditcard HTTP/1.1
Host: connect-testing.secuconnect.com
Authorization: Bearer qb56tjj1bcvo9n2nj4u38k84lo
Content-Type: application/json
Accept: application/json
 
{
"container": {
"type": "credit_card",
"private": {
"owner": "Max Mustermann",
"pan": "463544XXXXXX2298",
"expiration_date": "2034-02-01T00:00:00+00:00",
"issuer": "VISA",
"transact_container": "MzkzOTQ0MGI1YTBmMDg2ZDkxYTEwNzIyZTMwNTgwNGZjYTU3...",
"transact_skey_pubkey": "8ebccbb725d89d6286f227e672f24155e8b50b9688e7a45b...",
"transact_skey_keyname": "spp_2025.pem",
"transact_hash": "671439c1a91466df0249d8ab1b3595b682def08b1aea05a2d66e6adcf3d37a98"
}
},
"callback_urls": {
"success_url": "https://shop.example.com/payment/success?nonce=ciix8j3qbqffg8dcdc7b",
"failure_url": "https://shop.example.com/payment/failure?nonce=ciix8j3qbqffg8dcdc7b"
}
}

Or, when returned to the success URL by Smart Checkout, you would call something like GET /api/v2/Smart/Transactions/STX_3Z8EUQX0A2PBHRJV9FRY7P56GEDZAK.

In both cases the API would respond with 200 OK and an updated Smart Transaction like this:

Response
HTTP/1.1 200 OK
Content-Type: application/json
 
{
"object": "smart.transactions",
"id": "STX_3Z8EUQX0A2PBHRJV9FRY7P56GEDZAK",
// ...
"container": {
"object": "payment.containers",
"id": "PCT_3JU4VGYZF2XY8EJHH9FQ7WGYNZGJA4",
"type": "credit_card",
// ...
"token_status": {
"status": "failed",
// ...
}
},
"transactions": [
{
"object": "payment.transactions",
"id": "PCI_W026W643US3TWCGZA0AVZ248W8TSMW",
"trans_id": 123456789,
"transaction_hash": "abcdefghijkl12345678"
}
],
"created": "2025-02-25T15:55:58+01:00",
"updated": "2025-02-25T15:56:16+01:00",
"status": "created",
// ...
"payment_method": "creditcard",
"trans_id": 123456789,
"iframe_url": "https://connect-testing.secuconnect.com/spp/challenge/?token=5ab8b08...",
// ...
}

Please note container.token_status.status being "failed" (line 14).

In this case don't save the Payment Container details, and manage the situation.

Create the Smart Transaction for Subsequent Payments

When you create the Smart Transaction for later payments:

  • You can remove the flag "merchant_initiated" from "payment_context" (s. Recurring Payments (Legacy))
  • You must add different "mit_instructions" to "payment_context"; it must contain the flag "type": "mit" and pass the Payment Transaction ID (PCI_…) as "cit_reference"

The changed parts would look like here:

Request
POST /api/v2/Smart/Transactions HTTP/1.1
Host: connect-testing.secuconnect.com
Authorization: Bearer qb56tjj1bcvo9n2nj4u38k84lo
Content-Type: application/json
Accept: application/json
 
{
// ...
"payment_context":
{
// ...
// remove: "merchant_initiated": true
        "mit_instructions":
{
"type": "mit",
"cit_reference": "PCI_6UKN8UE29BH6EKF42JS6325AG34WMY"
}
    }
}

If everything is fine, the API responds with 200 OK and the created Smart Transaction.

Please note the following different elements inside "mit_instructions":

Field

Type

Meaning

type

string

MIT transactions ("mit") for subsequent payment now

cit_reference

string

Payment Transaction ID (PCI_…) of the first payment

The other object "container_instructions" is no longer needed.

If everything is fine, the API responds with 200 OK and the created Smart Transaction. There is nothing special in the responded Smart Transaction.

Authorise and Capture the Subsequent Payment

With the call to authorise the payment, you would pass the Payment Container ID only instead of all the details:

Request
POST /api/v2/Smart/Transactions/STX_HUXEQ5X302PBHTEYWP66F9AX0N44A4/prepare/creditcard HTTP/1.1
Host: connect-testing.secuconnect.com
Authorization: Bearer qb56tjj1bcvo9n2nj4u38k84lo
Content-Type: application/json
Accept: application/json
 
{
"container": {
"id": "PCT_3JU4VGYZF2XY8EJHH9FQ7WGYNZGJA4",
},
"callback_urls": {
"success_url": "https://shop.example.com/payment/success?nonce=ciix8j3qbqffg8dcdc7b",
"failure_url": "https://shop.example.com/payment/failure?nonce=ciix8j3qbqffg8dcdc7b"
}
}

This is not different than before.

If everything is fine, the API responds again with 200 OK and the updated Smart Transaction:

Response
HTTP/1.1 200 OK
Content-Type: application/json
 
{
"object": "smart.transactions",
"id": "STX_HUXEQ5X302PBHTEYWP66F9AX0N44A4",
// ...
"container": {
"object": "payment.containers",
"id": "PCT_3JU4VGYZF2XY8EJHH9FQ7WGYNZGJA4",
"type": "credit_card"
},
"transactions": [
{
"object": "payment.transactions",
"id": "PCI_54UPYB6SGWC7PQCBXHX99248W8UWMJ",
"trans_id": 123456791,
"transaction_hash": "bcdefghijklm223456789"
}
],
"created": "2026-05-10T16:58:34+01:00",
"updated": "2026-05-10T17:00:40+01:00",
"status": "ok",
// ...
"payment_method": "creditcard",
"trans_id": 123456791,
// ...
}

The payment is authorised or already captured (if accompanied by the auto_capture flag). Please check the payment status.

Network Token Lifecycle

Manage Status Changes of the Network Token

Beginning with our new acquiring solution, we will also start to send push notifications for Network Token status changes. This can be used to activate or to remove the Payment Container. The push notification is sent for the Payment Container holding the Network Token.

All details are found here: Network Token Status Notifications

Archiving the Network Token

Beginning with our new acquiring solution, you can request the deletion or archiving the network token.

All details are found here: Archiving the Network Token