Example Use Cases

3D Secure Transaction

Steps

  1. Get Bluefin authorization credentials, which will be used to ensure security by signing the Request URL:

    1. merchantId
    2. secretKey
  2. Server - Create a web server exposing two routes so let's use a Node.js server as an example

    1. Create Payment URL (I - Handles initial transaction data if any / O - Returns the encoded Request Url signed):

      1. Use the Secure Hash parameters to make the Hash calculation:

        1. You can use this Bash script.

        2. In Node.js, the equivalent could be:

          import { createHash } from 'crypto'
          import 'dotenv/config'
          
          const mid = process.env.MID
          const sKey = process.env.SKEY
          
          app.post('/get-tecsweb-token', async (req, res) => {
            const { amt, txcur, rurl } = req.body
          
            if (!amt || !txcur || !rurl) {
              return res.status(400).json({ error: 'invalid initial payment data' })
            }
          
            const urlMap = new Map()
            urlMap.set('mid', mid)
            urlMap.set('amt', amt)
            urlMap.set('txid', '' + Date.now())
            urlMap.set('txcur', txcur)
            urlMap.set('txdesc', 'Transaction Description')
            urlMap.set('receiptnumber', '123456')
            urlMap.set('rurl', rurl)
          
            const signData = `${urlMap.get('amt')}|${urlMap.get('txid')}|${urlMap.get('txcur')}|${urlMap.get('txdesc')}|${urlMap.get('mid')}|${urlMap.get('rurl')}${sKey}`
          
            const hash = createHash('sha256')
              .update(signData)
              .digest('binary')
              .split('')
              .map(char => char.charCodeAt(0).toString(16).padStart(2, '0'))
              .join('').toUpperCase()
          
            urlMap.set('sign', hash)
            // see below
          })
          
        3. The transaction ID needs to be unique, so Date.now() is being used. Feel free to use your logic generating a unique ID. For example, a sequence of random integers, etc. We recommend using the current date time for uniqueness.

      2. Let's calculate and attach the Date-Time-TX parameter

          const padZero = (num) => {
            return String(num).padStart(2, '0');
          }
        
          const makeTransactionDateTime = () => {
            const currentDate = new Date();
        
            const year = currentDate.getFullYear();
            const month = padZero(currentDate.getMonth() + 1);
            const day = padZero(currentDate.getDate());
            const hours = padZero(currentDate.getHours());
            const minutes = padZero(currentDate.getMinutes());
            const seconds = padZero(currentDate.getSeconds());
        
            const formattedDate = `${year}${month}${day}${hours}${minutes}${seconds}`;
            return formattedDate;
          }
        
        urlMap.set('Date-Time-TX', makeTransactionDateTime())
        
      3. Iterate over each parameter to encode its value:

        let path = ''
        
        const appendURLComp = (val, key) => {
          const encodedValue = encodeURIComponent(val).replace('%20', '+')
          path += key == 'mid' ? `?${key}=${encodedValue}` : `&${key}=${encodedValue}`
        }
        
        urlMap.forEach(appendURLComp)
        
      4. Concatenate the encoded path to the TECS WEB API Endpoint

      5. Return the signed Request URL to the Client:

        const baseUrl = 'https://test.tecs.at/tecsweb/tecswebmvc_start.do'
        return res.json({ signedUrl: baseUrl + path })
        
    2. Payment Response (I - Response URL containing the transaction data / O - as you see fit):

      1. You can get the transaction data from URL query parameters

      2. Handles the response as it best suits your application.

        1. For example, let's return a new HTML document with the transaction response and some other data:
        app.get('/payment-response', (req, res) => {
          const { responsecode, responsetext, CardReferenceNumber, sign } = req.query
        
          res.end(`
              <html>
                <head>
                  <script src="https://test.tecs.at/tecsweb/js/tecsweb.js"></script>
                </head>
                <body>
                  <div>
                    <p>Response code: ${responsecode} </p><br />
                    <p>Response text: ${responsetext} </p><br />
                    <p>Card Reference Number: ${CardReferenceNumber} </p><br />
                    <p>Sign: ${sign} </p>
                  </div>
                </body>
              </html>
            ` )
        })
        
  3. Client - front-end application (I - As you see fit / O - Redirect to the signed Request URL):

    1. Make an HTTP request to the Create Payment URL route to get the signed Request URL.
      1. Here, you can store some initial transaction values that might be defined on the client side.
        1. For example, we are storing the amount, transaction currency and landing page after the transaction is processed (Return URL):
        <html>
            <head>
            </head>
            <body>
              <script>
                const initTransactionData = {
                  amt: '100',
                  txcur: 'EUR',
                  rurl: 'http://127.0.0.1:3000/payment-response'
                }
                ...
        
    2. Make HTTP Request to receive the Request URL:
      fetch('http://127.0.0.1:3000/get-tecsweb-token', {
        method: 'POST',
        headers: {
          "Content-type": "application/json"
        },
        body: JSON.stringify(initTransactionData)
      })
      
    3. Once the server returns the signed Request URL, the developer redirects to the returned URL:
      1. For example, we could use the href method:
               fetch('http://127.0.0.1:3000/get-tecsweb-token', {
                  method: 'POST',
                  headers: {
                    "Content-type": "application/json"
                  },
                  body: JSON.stringify(initTransactionData)
                })
                  .then(response => response.json())
                  .then(data => {
                    window.location.href = data.signedUrl;
                  })
                  .catch((error) => {
                    console.error('Error:', error);
                  });
                </script>
            </body>
        </html>
        
  4. Once the Client and Server applications are configured:

    1. Trigger the Client application
    2. The web shop receives the Response URL, in our case GET /payment-response - whether the transaction was authorized, the amount, and the rest of the transaction data.

Note:

If a developer prefers to use the PHP programming language, they can make use of PHP SDK and make a transaction in fewer steps. Please refer to the Quickstart Guide for the instructions.

Description

The MPI simulator allows developers and testers to simulate 3D Secure authentication flows without actually connecting to live payment networks. The MPI simulator helps test various scenarios, such as successful and failed authentication attempts, to ensure that the integration with TECS Web and the overall 3D Secure process works correctly before going live.

See more about 3D Secure protocol at https://en.wikipedia.org/wiki/3-D_Secure.

Here, we test a PRE-AUTH transaction in order to demonstrate 3D Secure authentication flows using the MPI simulator.

For PRE-AUTH transactions, it is important to add Txorigid=5 to the request URL. To redirect the URL, see the Quickstart Guide.

PHP Request URL Generation

<?php
  require 'vendor/autoload.php';
  
  function padZero($num) {
    return str_pad($num, 2, '0', STR_PAD_LEFT);
  }

  function makeTransactionDateTime() {
    $currentDate = new DateTime();

    $year = $currentDate->format('Y');
    $month = padZero($currentDate->format('n'));
    $day = padZero($currentDate->format('j'));
    $hours = padZero($currentDate->format('G'));
    $minutes = padZero($currentDate->format('i'));
    $seconds = padZero($currentDate->format('s'));

    $formattedDate = $year . $month . $day . $hours . $minutes . $seconds;
    return $formattedDate;
  }

  $tecs = new \Tecs\TecsWeb(
    'SecretKey',
    'MerchantId',
    'https://test.tecs.at/tecsweb/tecswebmvc_start.do'
  );

  try {
    $tecsWebRequestToken = $tecs->createSignedUrl([
      \Tecs\TecsWeb::AMOUNT         => '900',
      \Tecs\TecsWeb::TX_ID          => '30',
      \Tecs\TecsWeb::TX_CURRENCY    => 'EUR',
      \Tecs\TecsWeb::TX_DESC        => 'Transaction Description',
      \Tecs\TecsWeb::RECEIPT_NUMBER => '123456',
      \Tecs\TecsWeb::RETURN_URL     => 'http://127.0.0.1:8000/payment-response',
      \Tecs\TecsWeb::TX_ORIG_ID     => '5',
      \Tecs\TecsWeb::ORIG_TX_ID     => '29',
      \Tecs\TecsWeb::MESSAGE_TYPE   => '1',
      \Tecs\TecsWeb::TX_PLACE       => 'MAUTAUFSICHT',
      \Tecs\TecsWeb::TX_DATE_TIME   => makeTransactionDateTime(),
  } catch (\Exception $e) {
    // ... Handle exception
  }

?>

For the full list of transaction types, refer to the Table of Transaction Types.

With that in mind, we are left with something like the following.

Request URL

https://test.tecs.at/tecsweb/tecswebmvc2.do
?mid=11450002
&sign=120E62EB3E3B8D084B6A2237C9E8DDC1E8803F8698062C102017D38B399EA550
&amt=900
&txid=30
&txcur=EUR
&txdesc=Transaction+Description
&receiptnumber=123457&rurl=http%3A%2F%2F127.0.0.1%3A8000%2Fpayment-response
&Txorigid=5
&origTRXNum=29
&Message-Type=1
&Transaction-Place=MAUTAUFSICHT
&Date-Time-TX=20240508115528

To complete a PRE-AUTH transaction, jump to 3D Secure Transaction PRE-AUTH with Completion.

3D Secure Transaction with Zero Amount

You can save the customer's payment details by specifying the amount value as zero. In this scenario, a different endpoint to the payment portal is used: /tecswebmvc2_verify.do.

This type of transaction can be referred to as a saving card transaction.

In accordance with the procedure for manual hash calculation, you first calculate the HMAC signature with zero amount.

Hash Calculation

#!/bin/bash
AMT='0'
TransactionId='38'
txCur='EUR'
txDesc='Transaction Description'
MerchantId='MerchantId'
RURL='http://127.0.0.1:8000/payment-response'
skey='SecretKey'
sigData_zero_amount="$AMT|$TransactionId|$txCur|$txDesc|$MerchantId|$RURL$skey"
signature_zero_amount=`echo -n "$sigData_zero_amount" | openssl dgst -sha256 -binary | xxd -p`
S2=`echo -n $signature_zero_amount | awk '{print toupper($0)}'`
echo "Zero Amount HMAC Signature: $S2"

Then, you assemble a URL with the required parameters.

Request URL

https://test.tecs.at/tecsweb/tecswebmvc2_verify.do
?mid=11450002
&sign=463D356B9843D01D67DB5C2057398179B53045278F5784EB7B7764082C803C70
&amt=0
&txid=38
&txcur=EUR
&txdesc=Transaction+Description
&receiptnumber=123456
&rurl=http%3A%2F%2F127.0.0.1%3A8000%2Fpayment-response
&origTRXNum=39
&Message-Type=1
&Transaction-Place=MAUTAUFSICHT
&Date-Time-TX=20240508120042

NOTE: The amount in this URL stays at zero as well.

3D Secure Transaction, Storing Payment Card on Client Side, COF/MIT/CIT

This type of transaction can be performed after 3D Secure transaction with or without a zero amount. It is usually used after the latter because it allows you to extract the card reference without making a transaction with an actual amount.

Zero amount transactions are especially useful for recurring payments such as the following:

  • Card-on-file transactions (COF)

  • Merchant-initiated transactions (MIT)

  • Customer-initiated transactions (CIT)

First, you generate the request URL for either of the two transactions above.

In this case, we use the zero amount one.

Request URL

https://test.tecs.at/tecsweb/tecswebmvc2_verify.do
?mid=11450002
&sign=463D356B9843D01D67DB5C2057398179B53045278F5784EB7B7764082C803C70
&amt=0
&txid=38
&txcur=EUR
&txdesc=Transaction+Description
&receiptnumber=123456
&rurl=http%3A%2F%2F127.0.0.1%3A8000%2Fpayment-response
&origTRXNum=39
&Message-Type=1
&Transaction-Place=MAUTAUFSICHT
&Date-Time-TX=20240508120042

After you submit the form by clicking on "Save Card", you receive the following URL in response.

Response URL

http://127.0.0.1:8000/payment-response
?responsecode=0
&responsetext=Authorized
&mid=11450002
&txid=38
&Date-Time-TX=20240508120042
&Authorization-number=001113
&VU-NUMMER=20240419072544
&Operator-ID=10
&SERIEN-NR=&Orig-TX-ID=00000000000000000000
&STAN=21072
&Orig-STAN=0
&SVC=000
&UserData=&CardReferenceNumber=REF94441301938417231111_2412_1111_444422
&sign=463D356B9843D01D67DB5C2057398179B53045278F5784EB7B7764082C803C70
&AcquirerName=TECS+Offline
&CardType=MASTERCARD

Then, you extract the CardReferenceNumber - this part in particular: REF94441301938417231111.

Now, on the server side, we execute recurring payments using the merchant services API and the CardReferenceNumber.

REST API Request

POST https://{-*}.tecs.at/merchantservices/public/paymentTransaction

{
    method: "POST",
    headers: {
      "Authorization": "{authKey}",
      "Content-Type": "application/json",
    },
    body: `{
      "cardNumberReference": "REF94441301938417231111",
      "transactionType": "AUTHORIZATION",
      "transactionId": "20240509193958271",
      "transactionDate": "20240509193958",
      "terminalId": {terminalId},
      "clientId": 1,
      "cvc": "",
      "amount": 400,
      "currency": "EUR",
      "receiptNumber": "01",
      "paymentReason": "test sale",
      "terminalLocation": "BA",
      "password": "{terminalPassword}",
      "ecData": "",
      "ecrData": "",
      "emvData": "",
      "languageCode": "EN",
      "receiptLayout": 99
    }`
}

Body Parameters

  • terminalPassword (string) (required)
    • To get the terminal password from your PAM, go to: Merchant & Terminals -> Merchants -> ALL PRODUCTS and click on the key icon to show the Ecom parameters.

3D Secure Transaction and Recurring Transaction with Card Reference (Payment Token)

Unlike the previous use case, here we are performing a 3DS transaction. The type of transaction can be set to either Txorigid=5 (PRE-AUTH) or Txorigid=2 (SALE).

The transaction origin identifier (Txorgid) is by default sale: 2 and it is not required as a parameter.

Request URL

https://test.tecs.at/tecsweb/tecswebmvc2.do
?mid=11450002
&sign=463D356B9843D01D67DB5C2057398179B53045278F5784EB7B7764082C803C70
&amt=100
&txid=44
&txcur=EUR
&txdesc=Transaction+Description
&receiptnumber=123456
&rurl=http%3A%2F%2F127.0.0.1%3A8000%2Fpayment-response
&Txorigid=4
&origTRXNum=43
&Message-Type=1
&Transaction-Place=MAUTAUFSICHT
&Date-Time-TX=20240509215022

Response URL

http://127.0.0.1:8000/payment-response
?responsecode=0
&responsetext=Authorized
&mid=11450002
&txid=44
&Date-Time-TX=20240509215022
&Authorization-number=002202
&VU-NUMMER=20240419072544
&Operator-ID=10
&SERIEN-NR=&Orig-TX-ID=00000000000000000000
&STAN=21081
&Orig-STAN=0
&SVC=000&User-Data=&CardReferenceNumber=REF94471221557166071111_2412_1111_444433
&sign=463D356B9843D01D67DB5C2057398179B53045278F5784EB7B7764082C803C70
&AcquirerName=TECS+Offline
&CardType=VISA

Now, just as described in the previous example, you use CardReferenceNumber: REF94471221557166071111 to execute a recurring payment request against the merchant services API.

REST API Request

POST https://{-*}.tecs.at/merchantservices/public/paymentTransaction

{
    method: "POST",
    headers: {
      "Authorization": "{authKey}",
      "Content-Type": "application/json",
    },
    body: `{
      "cardNumberReference": "REF94441301938417231111",
      "transactionType": "AUTHORIZATION",
      "transactionId": "20240509193958271",
      "transactionDate": "20240509193958",
      "terminalId": {terminalId},
      "clientId": 1,
      "cvc": "",
      "amount": 400,
      "currency": "EUR",
      "receiptNumber": "01",
      "paymentReason": "test sale",
      "terminalLocation": "BA",
      "password": "{terminalPassword}",
      "ecData": "",
      "ecrData": "",
      "emvData": "",
      "languageCode": "EN",
      "receiptLayout": 99
    }`
}

Body Parameters

  • terminalPassword (string) (required)
    • To get the terminal password from your PAM, go to: Merchant & Terminals -> Merchants -> ALL PRODUCTS and click on the key icon to show the Ecom parameters.

3D Secure Transaction PRE-AUTH with Completion

First, we use Txorigid=5 to generate the request URL in order to specify PRE-AUTH as our transaction type.

Request URL

https://test.tecs.at/tecsweb/tecswebmvc2.do
?mid=11450002
&sign=463D356B9843D01D67DB5C2057398179B53045278F5784EB7B7764082C803C70
&amt=100
&txid=51
&txcur=EUR
&txdesc=Transaction+Description
&receiptnumber=123456
&rurl=http%3A%2F%2F127.0.0.1%3A8000%2Fpayment-response
&Txorigid=5
&origTRXNum=50
&Message-Type=1
&Transaction-Place=MAUTAUFSICHT
&Date-Time-TX=20240509221648

Response URL

http://127.0.0.1:8000/payment-response
?responsecode=0
&responsetext=Authorized
&mid=11450002
&txid=51
&Date-Time-TX=20240509221648
&Authorization-number=002226
&VU-NUMMER=20240419072544
&Operator-ID=10
&SERIEN-NR=&Orig-TX-ID=00000000000000000000
&STAN=21083
&Orig-STAN=0
&SVC=000
&User-Data=&CardReferenceNumber=REF94471221557166071111_2412_1111_444433
&sign=463D356B9843D01D67DB5C2057398179B53045278F5784EB7B7764082C803C70
&AcquirerName=TECS+Offline
&CardType=VISA

With a PRE-AUTH transaction pending, we proceed with pre-authorization completion using the merchant services API. The completion could be done in next days/weeks even months.

REST API Request

POST https://{-*}.tecs.at/merchantservices/public/preAuthCompletionTransaction

{
    method: "POST",
    headers: {
      "Authorization": "{authKey}",
      "Content-Type": "application/json",
    },
    body: `{
      "transactionId": "20240509221803866",
      "transactionDate": "20240509221803",
      "terminalId": {terminalId},
      "clientId": 1,
      "amount": 100,
      "currency": "EUR",
      "receiptNumber": "01",
      "paymentReason": "test completion",
      "originalTransactionId": "51"
    }`
}

3D Secure Transaction and Storing Payment Card Reference in TECS Web

For the complete diagram of 3D Secure transaction flow, check out 3D Secure Transaction.

Card holder identification (CHI)

We can also store the card reference after a 3DS transaction in TECS Web.

If the CHI parameter is set to 0 in the request URL, TECS Web automatically generates a CHI and returns it in the response URL as User-Data. The CHI could be also generated by the merchant, but it must be unique per terminalId.

NOTE: every URL parameter needs to be URL encoded.

Request URL

https://test.tecs.at/tecsweb/tecswebmvc2.do
?mid=11450002
&sign=463D356B9843D01D67DB5C2057398179B53045278F5784EB7B7764082C803C70
&amt=100
&txid=38
&txcur=EUR
&txdesc=Transaction+Description
&receiptnumber=123456
&rurl=http%3A%2F%2F127.0.0.1%3A8000%2Fpayment-response
&origTRXNum=37
&Message-Type=1
&Transaction-Place=MAUTAUFSICHT
&Date-Time-TX=20240509211534
&User-data=CHI%3D0%3B

Response URL

http://127.0.0.1:8000/payment-response
?responsecode=0
&responsetext=Authorized
&mid=11450002
&txid=38
&Date-Time-TX=20240509203112
&Authorization-number=002173
&VU-NUMMER=20240509211534
&Operator-ID=10
&SERIEN-NR=&Orig-TX-ID=00000000000000000000
&STAN=21078
&Orig-STAN=0
&SVC=000&User-Data=CHI%3D94471221557166071111
&CardReferenceNumber=REF94471221557166071111_2412_1111_444433
&sign=463D356B9843D01D67DB5C2057398179B53045278F5784EB7B7764082C803C70
&AcquirerName=TECS+Offline
&CardType=VISA

CHI storage can deliver a smoother and more convenient checkout process for customers. With verified CHI, customers may not need to enter their payment details repeatedly, which improves the overall user experience and reduces friction during transactions. This is a way of auto-filling the payment form with the cardholder's information.

To achieve this, reuse the saved CHI in the request URL.

User-Data=CHI%3D94471221557166071111

In the PHP SDK:

$tecsWebRequestToken = $tecs->createSignedUrl([
  \Tecs\TecsWeb::AMOUNT         => '100',
  \Tecs\TecsWeb::TX_ID          => '38',
  \Tecs\TecsWeb::TX_CURRENCY    => 'EUR',
  \Tecs\TecsWeb::TX_DESC        => 'Transaction Description',
  \Tecs\TecsWeb::RECEIPT_NUMBER => '123456',
  \Tecs\TecsWeb::RETURN_URL     => 'http://127.0.0.1:8000/payment-response',
  \Tecs\TecsWeb::ORIG_TX_ID     => '37',
  \Tecs\TecsWeb::MESSAGE_TYPE   => '1',
  \Tecs\TecsWeb::TX_PLACE       => 'MAUTAUFSICHT',
  \Tecs\TecsWeb::TX_DATE_TIME   => makeTransactionDateTime(),
  \Tecs\TecsWeb::USER_DATA      => 'CHI=94471221557166071111;',
]);

For the rest of the PHP code, refer to the 3D Secure Transaction use case.