AltaPay - How to tokenize a terminal

AltaPay is a payment provider (PSP) allowing both VISA, Mastercard and Dankort. AltaPay as a payment providers provides both payment windows (terminal) for embedding into the customer flow, and/or popup windows for direct payment.

If you are reading this, there is a high chance you use AltaPay as your preferred payment provider. We respect your choice of this.

Some background
As subscription payments are conducted during the nightly shifts (00:00 where you are a sleep), you will need to tokenize the payment card for later use before signing up a customer. Tokenization is widely used in the PSP industry, however follows these steps to ensure AltaPay tokenizes the payment.

🚧

Retrieve the token from a one-off payment

NB! If you are processing a one-off payment i.e. from an e-commerce ordre, you might be able just to retrieve the payment token from the initial order, and then return this to Upodi.

To continue you will need your credentials (username:password) to AltaPay and name of terminal (terminalname).

First - register a payment

curl -X GET \
  'https://testgateway.altapaysecure.com/merchant/API/createPaymentRequest?terminal={{TERMINALNAME}}&shop_orderid={{ORDERID}}&amount=0.01&currency=DKK' \
  -H 'Accept: */*' \
  -u username:password \
  -H 'Cache-Control: no-cache' \
  -H 'Connection: keep-alive' \
  -H 'accept-encoding: gzip, deflate' \
  -H 'cache-control: no-cache' \

Following this request, retrieve the payment link (URL) from the response:

<?xml version="1.0"?>
<APIResponse version="20170228">
    <Header>
        <Date>2018-11-20T11:36:38+02:00</Date>
        <Path>API/createPaymentRequest</Path>
        <ErrorCode>0</ErrorCode>
        <ErrorMessage/>
    </Header>
    <Body>
        <Result>Success</Result>
        <PaymentRequestId>....</PaymentRequestId>
        <Url>https://testgateway.altapaysecure.com/eCommerce/API/requestForm?pid=....</Url> <DynamicJavascriptUrl>https://testgateway.altapaysecure.com/eCommerce/API/embeddedPaymentWindow?pid=....</DynamicJavascriptUrl>
    </Body>
</APIResponse>

Using the payment link (URL or DynamicJavaScriptUrl), allow the user to provide the card and process the payment but redirecting the user. As the transaction completes, using the AltaPay form - return the transaction id.

Second - fetch the payment

Use the returned transaction id to get the payment. You may also use your payment id, shop order id (if unique) etc. See more using the AltaPay documentation here.

curl -X GET \
  'https://testgateway.altapaysecure.com/merchant/API/payments?shop_orderid={{ORDERID}}&transaction_id={{TRANSACTIONID}}' \
  -H 'cache-control: no-cache'

From the response return the token inline of the XML (CreditCardToken element), CCpLzB/iF7mTo6J02ywL/O0nT0Es1D1xV2sNmjKa7YLoV+BoLdPe1YbM0X//s1hSAG0cvKuA7vlj8Z86CFNvjg==+1 in this example.

<?xml version="1.0"?>
<APIResponse version="20170228">
    <Header>
        <Date>2018-11-20T11:39:00+02:00</Date>
        <Path>API/payments</Path>
        <ErrorCode>0</ErrorCode>
        <ErrorMessage/>
    </Header>
    <Body>
        <Result/>
        <ResultFilter>
            <ShopOrderIdEquals>...</ShopOrderIdEquals>
        </ResultFilter>
        <Transactions>
            <Transaction>
                <TransactionId>..</TransactionId>
                <PaymentId>..</PaymentId>
                <AuthType>payment</AuthType>
                <CardStatus>InvalidLuhn</CardStatus>
                <CreditCardExpiry>
                    <Year>2021</Year>
                    <Month>05</Month>
                </CreditCardExpiry>
 <CreditCardToken>CCpLzB/iF7mTo6J02ywL/O0nT0Es1D1xV2sNmjKa7YLoV+BoLdPe1YbM0X//s1hSAG0cvKuA7vlj8Z86CFNvjg==+1</CreditCardToken>
                ...

Third - release if needed

NB! If you did an inline form only to retrieve a tokenized card, you can release (void) the payment using the following request. If the request came as a result of an one-off payment, continue the flow.

curl -X GET \
  'https://testgateway.altapaysecure.com/merchant/API/releaseReservation?transaction_id={{TRANSACTIONID}}' \
  -H 'cache-control: no-cache'

Fourth - provide the token to Upodi

Provide the token (Example: CCpLzB/iF7mTo6J02ywL/O0nT0Es1D1xV2sNmjKa7YLoV+BoLdPe1YbM0X//s1hSAG0cvKuA7vlj8Z86CFNvjg==+1) to Upodi using the POST PaymentMethod API, with the following JSON as body:

{
  "type" : 64,
  "makedefault" : "true", /* will make the payment method default */
  "puretoken" : { 
    "token" : "CCpLzB/iF7mTo6J02ywL/O0nT0Es1D1xV2sNmjKa7YLoV+BoLdPe1YbM0X//s1hSAG0cvKuA7vlj8Z86CFNvjg==+1", /* AltaPay token */
    "paymentgateway" : "altapay"
  }
}

Testing the flow

AltaPay provide test data as follows here.