Pay by Link
Pay by Link is our hosted payment form solution that provides a flexible, secure, and easy way for your End-user's to pay with your enabled payment methods.
Use Pay by Link and redirect your shoppers to Novalnet-hosted checkout page if you want the fastest way to accept payments, if you don't want to host your own payment form, or if you're still building your website or app. Pay by Link is also iDEAL | Wero for businesses that accept orders through other channels, such as email or social media.
How does it work?
When a buyer wants to places an order, you can create a payment link, and send that link to your buyer through E-mail/ SMS. When they select the link, they will be redirected to the Novalnet's Hosted Payment page where they can choose to pay with their preferred payment method. After the Buyer pays, you receive the payment result through Novalnet's webhook notification (or) you can initiate the /transaction/details API call to retrieve the payment result.
You can customize the look and feel of the Novalnet's Seamless payment form by adding your display name, your brand logo, etc.
Link expiry and notification
By default, payment links expire after 24 hours. This integration is effective when you use URL Shortener additional service. Upon using this service, notify the server using the parameter hosted_page.url_shortener. The generated link using the parameter hosted_page.url_shortener will be valid until 21 days by default. Further customization can be done using the parameter hosted_page.link_expiry.
You can share the generated link with corresponding end-customer directly via E-mail (specified in customer.email parameter) by using the hosted_page.link_notify parameter.
Requirements
If you wish to use this feature then you need to follow the below procedure
- Need to enable the Pay by Link feature in Novalnet by contacting our support team
- Set up / send your callback URL to receive the payment response.
How to implement?
To use Pay by Link, you need to provide payment information such as amount, currency, end-customer details, etc. other than the sensitive payment data, and we'll generate a payment link that you can give to your end-customer. We have two options to create the payment link:
- Using the Pay by Link API - Submit an /seamless/payment API request and get the payment link from the response.
- Using Novalnet Admin Portal - Create the payment link through your Novalnet Admin Portal. This requires no development work
Using the Pay by Link API
Follow the below steps to perform the creation of the payment link via server-to-server API process
Step 1: Generating payment link
Post all the required transaction parameters to Novalnet in advance without the user interaction, thus submitting all the transaction based data (user/order details, merchant credentials, etc. other than the sensitive payment data) through server to server call, to create the payment URL (hosted at Novalnet server).
Parameter Reference
The sample in the steps below will contain only the minimal parameters for the demo execution and explanation. To know more about all the parameters, it's descriptions, header explanation and results, refer this >>link<<
Customization of payment page with your choice of layout & design
The payment page hosted at Novalnet is entirely customizable for the layout and design; you can adjust it as you desire. Please refer to the hosted_page block on the parameter reference link to customize the layout per stylesheet, header, footer, etc.
<?php
// Need to enter your payment access key value here
$payment_access_key = '###YOUR_PAYMENT_ACCESS_KEY###';
// Now, have to encode the $payment_access_key value with the base64 encode
$encoded_data = base64_encode($payment_access_key);
// Action Endpoint
$endpoint = 'https://payport.novalnet.de/v2/seamless/payment';
// Build the Headers array
$headers = [
// The Content-Type should be "application/json"
'Content-Type:application/json',
// The charset should be "utf-8"
'Charset:utf-8',
// Optional
'Accept:application/json',
// The formed authenticate value (case-sensitive)
'X-NN-Access-Key:' . $encoded_data,
];
$data = [];
// Build Merchant Data
$data['merchant'] = [
// Your API signature value
'signature' => '###YOUR_API_SIGNATURE###',
// Your corresponding tariff ID
'tariff' => '###YOUR_TARIFF_ID###'
];
// Build Customer Data
$data['customer'] = [
// Shopper's first name
'first_name' => 'Max',
// Shopper's last name
'last_name' => 'Mustermann',
// Shopper's email
'email' => '###YOUR_MAIL###',
// Shopper's Ip address
'customer_ip' => '###CUSTOMER_IP###',
// Shopper's customer number from the shop
'customer_no' => '###CUSTOMER_NUMBER###',
// Shopper's Telephone number
'tel' => '+49 089 123456',
// Shopper's Mobile number
//'mobile' => '+49 174 7781423',
// Shopper's birthdate value YYYY-MM-DD - Decomment it based on your usage
'birth_date' => '1992-06-10',
// Shopper's gender - Decomment it based on your usage
// 'gender' => 'u',
// Shopper's company vat ID value - Decomment it based on your usage
// 'vat_id' => 'DE123456',
// Shopper's company regestration number - Decomment it based on your usage
// 'reg_no' => 'HRB1234',
// Shopper's company tax ID value - Decomment it based on your usage
// 'tax_id' => '123/123/123',
// Shopper's session value - Decomment it based on your usage
// 'session' => 'fedgrgst5653653hdgfsvgdsf622627e',
// Shopper's fax number - Decomment it based on your usage
// 'fax' => '+49 89 654321',
// Shopper's billing address
'billing' => [
// House number
'house_no' => '2',
// Street
'street' => 'Musterstr',
// City
'city' => 'Musterhausen',
// zip
'zip' => '12345',
// Country's ISO code
'country_code' => 'DE',
// State
// 'state' => 'Berlin',
// Name of the company - Decomment it based on your usage
// 'company' => 'ABC GmbH'
],
/* Optional child object - Decomment it based on your usage
'shipping' => [
// Pass this parameter if the billing and the shipping address are identical
'same_as_billing' => '1',
// First name
'first_name' => 'Norbert',
// Last name
'last_name' => 'Maier',
// Email
'email' => '###YOUR_MAIL###',
// Street
'street' => 'Hauptstr',
// House number
'house_no' => '9',
// City
'city' => 'Kaiserslautern',
// zip
'zip' => '66862',
// Country's ISO code
'country_code' => 'DE',
// Telephone number
'tel' => '+49 089 123456',
// Name of the company
'company' => 'A.B.C. Gerüstbau GmbH',
// Mobile number
'mobile' => '+49 174 7781423',
// State
'state' => 'Berlin'
]
*/
];
// Build Transaction Data
$data['transaction'] = [
// The Payment type of the transaction
//'payment_type' => '###PAYMENT_TYPE###',
// The transaction Amount in smaller currency unit
'amount' => '###TRANSACTION_AMOUNT###',
// The transaction currency's ISO code
'currency' => '###TRANSACTION_CURRENCY###',
// The mode of the transaction
'test_mode' => '###TEST_MODE###',
// The order number of the transaction
'order_no' => '###TRANSACTION_ORDER_NUMBER###',
// Need to be specify this for the Redirect payment types to which you need to redirect on SUCCESS
'return_url' => '###YOUR_RETURN_URL###',
// Need to be specify this for the Redirect payment types to which you need to redirect on FAILURE (optional)
'error_return_url' => '###YOUR_ERROR_RETURN_URL###',
// The Notify URL value for this particular transaction
'hook_url' => '###HOOK_URL###',
// The flag to create the token for the payment data - Decomment it based on your usage
// 'create_token' => 1,
// Build Payment Data - Decomment it based on your usage
/*
'payment_data' => [
// Build your payment data based on your selected payment type
'token' => '###TOKEN###'
]
*/
];
// Hosted Payment page customizations
$data['hosted_page'] = [
// Change logo in the Hosted payment page
'logo' => '###YOUR_SHOP_LOGO###',
// Change the styling of the Hosted payment page - Decomment it based on your usage
// 'css_url' => '###YOUR_CSS_URL###',
// Payment types to be displayed in the Hosted Payment Page
// 'display_payments' => ['CREDITCARD', 'DIRECT_DEBIT_SEPA', 'INVOICE', 'IDEAL', 'PAYPAL'],
// Payment types to be hidden in the Hosted Payment Page - Used when necessary and display_payments when not in use
'hide_payments' => ['PRZELEWY24', 'DIRECT_DEBIT_ACH', 'BLIK'],
// Hide the following sections from the Hosted Payment Page
'hide_blocks' => ['ADDRESS_FORM', 'SHOP_INFO', 'LANGUAGE_MENU', 'HEADER', 'TARIFF'],
// Customize the display of the following pages
'skip_pages' => ['CONFIRMATION_PAGE', 'SUCCESS_PAGE', 'PAYMENT_PAGE'],
// URL shortner flag
'url_shortener' => 1,
// Need to specify the link expiry date here
'link_expiry' => date('Y-m-d', strtotime("+14 day")),
// Defines the way to share the payment link with the end-customer.
'link_notify' => ['EMAIL']
];
/*
// Subscription Data, used for processing Novalnet`s subscription - Optional object - Decomment it based on your usage
$data['subscription'] = [
// The interval between each cycle
'interval' => '1m',
// Subscription trial interval if applicable
'trial_interval' => '3m',
// Subscription trial interval amount if applicable
'trial_amount' => '150',
];
*/
/*
// Marketplace data, used for the affiliate`s marketplace model - Optional object - Decomment it based on your usage
$data['marketplace'] = [
// To submit amount for several affiliates to be booked
'tx_split' => [
'2261' => '20',
'2271' => '30',
],
];
*/
/*
// Affiliate Data, used for the affiliate`s revenue split model - Optional object - Decomment it based on your usage
$data['affiliate'] = [
// To submit shares for several affiliates for the same transaction
'subvendors'=> [
'2261' => '20',
'2271' => '30'
]
];
*/
// Custom Data - Optional object - Decomment it based on your usage
$data['custom'] = [
// Shopper's selected language in shop
'lang' => 'EN',
// Custom parameter's key
//'input1' => 'your internal reference parameter name',
// Custom parameter's value
//'inputval1' => 'your internal reference parameter value',
];
/*
// Invoicing Data, used for the additional invoicing service - Optional data object - Decomment it based on your usage)
$data['invoicing'] = [
// Overall invoice tax percent should mentioned here
'tax_percent' => 2,
// Overall invoice tax amount should mentioned here
'tax_amount' => 2,
// Total amount (excl. tax) should mentioned here
'net_amount' => 5000,
// Total amount (incl. tax) should mentioned here
'gross_amount' => 5000,
// Individual product details should mentioned here
'product_details' => [
[
'code' => 'P001',
'name' => 'Product name',
'group' => 'Product group',
'description' => 'Product description',
'quantity' => 2,
'unit' => 2,
'unit_price' => 100,
'total_price' => 200,
'tax_amount' => 1,
'tax_percent' => 1,
'discount' => 0,
'note' => 'Note about the product'
]
],
// Customize the customer support details here
'customer_support' => 'Max Mustermann | Email: support@yourshop.de',
// Custom Invoice number
'custom_invoice_no' => 'INV-32'
];
*/
// Convert the array to JSON string
$json_data = json_encode($data);
// Handle Response
$response = send_request($json_data, $endpoint, $headers);
function send_request($data, $url, $headers) {
// Initiate cURL
$curl = curl_init();
// Set the url
curl_setopt($curl, CURLOPT_URL, $url);
// Set the result output to be a string
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
// Set the POST value to true (mandatory)
curl_setopt($curl, CURLOPT_POST, true);
// Set the post fields
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
// Set the headers
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
// Execute cURL
$result = curl_exec($curl);
// Handle cURL error
if (curl_errno($curl)) {
echo 'Request Error:' . curl_error($curl);
return $result;
}
// Close cURL
curl_close($curl);
// Decode the JSON string
$result = json_decode($result);
return $result;
}
?>curl --location --request POST 'https://payport.novalnet.de/v2/seamless/payment' -H 'Content-Type: application/json' -H 'Charset:utf-8' -H 'Accept: application/json' -H 'X-NN-Access-Key: ###YOUR_ENCODED_PAYMENT_ACCESS_KEY###' -d '{"merchant":{"signature":"###YOUR_API_SIGNATURE###","tariff":"###YOUR_TARIFF_ID###"},"customer":{"first_name":"Max","last_name":"Mustermann","email":"###YOUR_MAIL###","customer_ip":"###CUSTOMER_IP###","customer_no":"###CUSTOMER_NUMBER###","tel":"+49 089 123456","mobile":"+49 174 7781423","billing":{"house_no":"2","street":"Musterstr","city":"Musterhausen","zip":"12345","country_code":"DE"}},"transaction":{"payment_type":"###PAYMENT_TYPE###","amount":"###TRANSACTION_AMOUNT###","currency":"###TRANSACTION_CURRENCY###","test_mode":"###TEST_MODE###","order_no":"###TRANSACTION_ORDER_NUMBER###","return_url":"###YOUR_RETURN_URL###","error_return_url":"###YOUR_ERROR_RETURN_URL###","hook_url":"###YOUR_HOOK_URL###"},"hosted_page":{"logo":"###YOUR_SHOP_LOGO###","hide_payments":["PRZELEWY24","DIRECT_DEBIT_ACH","BLIK"],"hide_blocks":["ADDRESS_FORM","SHOP_INFO","LANGUAGE_MENU","HEADER, TARIFF"],"skip_pages":["CONFIRMATION_PAGE","SUCCESS_PAGE","PAYMENT_PAGE"],"url_shortener":1,"link_expiry":"###LINK_EXPIRY###","link_notify":["EMAIL"]}}';#!/usr/bin/node
const https = require('https');
// data sent in the body of the request
const postData = JSON.stringify({
"merchant": {
"signature": "###YOUR_API_SIGNATURE###",
"tariff": "###YOUR_TARIFF_ID###"
},
"customer": {
"customer_ip": "###CUSTOMER_IP###",
"gender": "u",
"first_name": "Max",
"last_name": "Mustermann",
"email": "###YOUR_MAIL###",
"birth_date": "1992-06-10",
"billing": {
"street": "Musterstr",
"house_no": "2",
"city": "Musterhausen",
"zip": "12345",
"country_code": "DE",
"tel": "+49 089 123456"
}
},
"transaction": {
//"payment_type": "###PAYMENT_TYPE###",
"amount": "###TRANSACTION_AMOUNT###",
"currency": "###TRANSACTION_CURRENCY###",
"order_no": "###TRANSACTION_ORDER_NUMBER###",
"test_mode": "###TEST_MODE###",
"hook_url": "###YOUR_HOOK_URL###",
"return_url": "###YOUR_ERROR_RETURN_URL###",
"error_return_url": "###YOUR_HOOK_URL###"
},
"hosted_page": {
"logo": "###YOUR_SHOP_LOGO###",
"hide_payments": "{'PRZELEWY24','DIRECT_DEBIT_ACH','BLIK'}",
"hide_blocks": "{'ADDRESS_FORM', 'SHOP_INFO', 'LANGUAGE_MENU', 'HEADER', 'TARIFF'}",
"skip_pages": "{'CONFIRMATION_PAGE', 'SUCCESS_PAGE','PAYMENT_PAGE'}",
"url_shortener": 1,
"link_expiry": "date('Y-m-d', strtotime('+14 day'))",
"link_notify": "{'EMAIL'}"
}
});
const options = {
hostname: 'payport.novalnet.de',
port: 443,
path: '/v2/seamless/payment',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(postData),
'Charset': 'utf-8',
'Accept': 'application/json',
'X-NN-Access-Key': '###YOUR_ENCODED_PAYMENT_ACCESS_KEY###'
},
};
const req = https.request(options, (res) => {
console.log('statusCode:', res.statusCode);
// console.log('headers:', res.headers);
res.on('data', (d) => {
process.stdout.write(d);
});
});
req.on('error', (e) => {
console.error('ERROR: ',e);
});
// Write data to request body
req.write(postData);
req.end();#!/usr/bin/python3
import http.client
import json
CONN = http.client.HTTPSConnection("payport.novalnet.de")
PAYLOAD = json.dumps({
"merchant": {
"signature": "###YOUR_API_SIGNATURE###",
"tariff": "###YOUR_TARIFF_ID###"
},
"customer": {
"customer_ip": "###CUSTOMER_IP###",
"gender": "u",
"first_name": "Max",
"last_name": "Mustermann",
"email": "###YOUR_MAIL###",
"birth_date": "1983-07-02",
"billing": {
"street": "Musterstr",
"house_no": "2",
"city": "Musterhausen",
"zip": "12345",
"country_code": "DE",
"tel": "+49 089 123456"
}
},
"transaction": {
#"payment_type": "###PAYMENT_TYPE###",
"amount": "###TRANSACTION_AMOUNT###",
"currency": "###TRANSACTION_CURRENCY###",
"order_no": "###TRANSACTION_ORDER_NUMBER###",
"test_mode": "###TEST_MODE###",
"hook_url": "###YOUR_HOOK_URL###",
"return_url": "###YOUR_ERROR_RETURN_URL###",
"error_return_url": "###YOUR_HOOK_URL###"
},
"hosted_page": {
"logo": "###YOUR_SHOP_LOGO###",
"hide_payments": "{'PRZELEWY24','DIRECT_DEBIT_ACH','BLIK'}",
"hide_blocks": "{'ADDRESS_FORM', 'SHOP_INFO', 'LANGUAGE_MENU', 'HEADER', 'TARIFF'}",
"skip_pages": "{'CONFIRMATION_PAGE', 'SUCCESS_PAGE','PAYMENT_PAGE'}",
"url_shortener": 1,
"link_expiry": "date('Y-m-d', strtotime('+14 day'))",
"link_notify": "{'EMAIL'}"
}
})
HEADERS = {
'Content-Type': 'application/json',
'Charset': 'utf-8',
'Accept': 'application/json',
'X-NN-Access-Key': '###YOUR_ENCODED_PAYMENT_ACCESS_KEY###'
}
CONN.request("POST", "/v2/seamless/payment", PAYLOAD, HEADERS)
RES = CONN.getresponse()
DATA = RES.read()
print(DATA.decode("utf-8"))#!/usr/lib/ruby
require "uri"
require "json"
require "net/http"
url = URI("https://payport.novalnet.de/v2/seamless/payment")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["Accept"] = "application/json"
request["Charset"] = "utf-8"
request["X-NN-Access-Key"] = "###YOUR_ENCODED_PAYMENT_ACCESS_KEY###"
request.body = JSON.dump({
"merchant": {
"signature": "###YOUR_API_SIGNATURE###",
"tariff": "###YOUR_TARIFF_ID###"
},
"customer": {
"gender": "u",
"first_name": "Max",
"last_name": "Mustermann",
"email": "###YOUR_MAIL###",
"customer_ip": "###CUSTOMER_IP###",
"customer_no": "###CUSTOMER_NUMBER###",
"birth_date": "1992-06-10",
"billing": {
"street": "Musterstr",
"house_no": "2",
"city": "Musterhausen",
"zip": "12345",
"country_code": "DE",
"company": "ABC GmbH"
}
},
"transaction": {
# "payment_type": "###PAYMENT_TYPE###",
"amount": "###TRANSACTION_AMOUNT###",
"currency": "###TRANSACTION_CURRENCY###",
"order_no": "###TRANSACTION_ORDER_NUMBER###",
"test_mode": "###TEST_MODE###",
"hook_url": "###YOUR_HOOK_URL###",
"return_url": "###YOUR_ERROR_RETURN_URL###",
"error_return_url": "###YOUR_HOOK_URL###"
},
"hosted_page": {
"logo": "###YOUR_SHOP_LOGO###",
"hide_payments": "{'PRZELEWY24','DIRECT_DEBIT_ACH','BLIK'}",
"hide_blocks": "{'ADDRESS_FORM', 'SHOP_INFO', 'LANGUAGE_MENU','HEADER', 'TARIFF'}",
"skip_pages": "{'CONFIRMATION_PAGE', 'SUCCESS_PAGE', 'PAYMENT_PAGE'}",
"url_shortener": 1,
"link_expiry": "date('Y-m-d', strtotime('+14 day'))",
"link_notify": "{'EMAIL'}"
}
})
response = https.request(request)
puts response.read_bodypackage main
import (
"fmt"
"strings"
"net/http"
"io/ioutil"
)
func main() {
url := "https://payport.novalnet.de/v2/seamless/payment"
method := "POST"
payload := strings.NewReader(`{
"merchant": {
"signature": "###YOUR_API_SIGNATURE###",
"tariff": "###YOUR_TARIFF_ID###"
},
"customer": {
"customer_ip": "###CUSTOMER_IP###",
"gender": "u",
"first_name": "Max",
"last_name": "Mustermann",
"email": "###YOUR_MAIL###",
"birth_date": "1983-07-02",
"billing": {
"street": "Musterstr",
"house_no": "2",
"city": "Musterhausen",
"zip": "12345",
"country_code": "DE",
"tel": "+49 089 123456"
}
},
"transaction": {
//"payment_type": "###PAYMENT_TYPE###",
"amount": "###TRANSACTION_AMOUNT###",
"currency": "###TRANSACTION_CURRENCY###",
"order_no": "###TRANSACTION_ORDER_NUMBER###",
"test_mode": "###TEST_MODE###",
"hook_url": "###YOUR_HOOK_URL###",
"return_url": "###YOUR_ERROR_RETURN_URL###",
"error_return_url": "###YOUR_HOOK_URL###"
},
"hosted_page": {
"logo": "###YOUR_SHOP_LOGO###",
"hide_payments": "{'PRZELEWY24','DIRECT_DEBIT_ACH','BLIK'}",
"hide_blocks": "{'ADDRESS_FORM', 'SHOP_INFO', 'LANGUAGE_MENU','HEADER','TARIFF'}",
"skip_pages": "{'CONFIRMATION_PAGE', 'SUCCESS_PAGE', 'PAYMENT_PAGE'}",
"url_shortener": 1,
"link_expiry": "date('Y-m-d', strtotime('+14 day'))",
"link_notify": "{'EMAIL'}"
}
}`)
client := &http.Client {
}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
return
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Accept", "application/json")
req.Header.Add("Charset", "utf-8")
req.Header.Add("X-NN-Access-Key", "###YOUR_ENCODED_PAYMENT_ACCESS_KEY###")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
}/* List of required libraries (see also the import statements below):
- commons-logging-1.2.jar
- httpasyncclient-4.1.5.jar
- httpclient-4.3.3.jar
- httpcore-4.4.16.jar
- httpcore-nio-4.4.16.jar
- httpmime-4.5.14.jar
- json-20230227.jar
- unirest-java-3.9.00.jar
*/
import java.io.*;
import org.json.JSONArray;
import org.apache.http.auth.*;
import org.apache.http.nio.conn.*;
import org.apache.http.concurrent.*;
import org.apache.http.nio.reactor.*;
import org.apache.commons.logging.*;
import org.apache.http.entity.mime.content.*;
import kong.unirest.*;
public class TokenizationCreate {
public static void main(String []args) throws Exception{
Unirest.config().connectTimeout(1000).socketTimeout(2000);
HttpResponse<String> response = Unirest.post("https://payport.novalnet.de/v2/seamless/payment")
.header("Content-Type", "application/json")
.header("Charset", "utf-8")
.header("Accept", "application/json")
.header("X-NN-Access-Key", "###YOUR_ENCODED_PAYMENT_ACCESS_KEY###")
.body("{
"merchant": {
"signature": "###YOUR_API_SIGNATURE###",
"tariff": "###YOUR_TARIFF_ID###"
},
"customer": {
"customer_ip": "###CUSTOMER_IP###",
"gender": "u",
"first_name": "Max",
"last_name": "Mustermann",
"email": "###YOUR_MAIL###",
"birth_date": "1992-06-10",
"billing": {
"street": "Musterstr",
"house_no": "2",
"city": "Musterhausen",
"zip": "12345",
"country_code": "DE",
"tel": "+49 089 123456"
}
},
"transaction": {
//"payment_type": "###PAYMENT_TYPE###",
"amount": "###TRANSACTION_AMOUNT###",
"currency": "###TRANSACTION_CURRENCY###",
"order_no": "###TRANSACTION_ORDER_NUMBER###",
"test_mode": "###TEST_MODE###",
"hook_url": "###YOUR_HOOK_URL###",
"return_url": "###YOUR_ERROR_RETURN_URL###",
"error_return_url": "###YOUR_HOOK_URL###"
},
"hosted_page": {
"logo": "###YOUR_SHOP_LOGO###",
"hide_payments": "{'PRZELEWY24','DIRECT_DEBIT_ACH','BLIK'}",
"hide_blocks": "{'ADDRESS_FORM', 'SHOP_INFO', 'LANGUAGE_MENU','HEADER', 'TARIFF'}",
"skip_pages": "{'CONFIRMATION_PAGE', 'SUCCESS_PAGE', 'PAYMENT_PAGE'}",
"url_shortener": 1,
"link_expiry": "date('Y-m-d', strtotime('+14 day'))",
"link_notify": "{'EMAIL'}"
}
}")
.asString();
System.out.println(response.getBody());
}
}using System;
using System.Net.Http;
namespace TokenizationCreateRequest
{
public class TokenizationCreate {
public string check_Tokenization_create_request() {
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://payport.novalnet.de/v2/seamless/payment");
request.Headers.Add("Charset", "utf-8");
request.Headers.Add("Accept", "application/json");
request.Headers.Add("X-NN-Access-Key", "###YOUR_ENCODED_PAYMENT_ACCESS_KEY###");
var content = new StringContent("{
"merchant": {
"signature": "###YOUR_API_SIGNATURE###",
"tariff": "###YOUR_TARIFF_ID###"
},
"customer": {
"customer_ip": "###CUSTOMER_IP###",
"gender": "u",
"first_name": "Max",
"last_name": "Mustermann",
"email": "###YOUR_MAIL###",
"birth_date": "1992-06-10",
"billing": {
"street": "Musterstr",
"house_no": "2",
"city": "Musterhausen",
"zip": "12345",
"country_code": "DE",
"tel": "+49 089 123456"
}
},
"transaction": {
//"payment_type": "###PAYMENT_TYPE###",
"amount": "###TRANSACTION_AMOUNT###",
"currency": "###TRANSACTION_CURRENCY###",
"order_no": "###TRANSACTION_ORDER_NUMBER###",
"test_mode": "###TEST_MODE###",
"hook_url": "###YOUR_HOOK_URL###",
"return_url": "###YOUR_ERROR_RETURN_URL###",
"error_return_url": "###YOUR_HOOK_URL###"
},
"hosted_page": {
"logo": "###YOUR_SHOP_LOGO###",
"hide_payments": "{'PRZELEWY24','DIRECT_DEBIT_ACH','BLIK'}",
"hide_blocks": "{'ADDRESS_FORM', 'SHOP_INFO', 'LANGUAGE_MENU','HEADER', 'TARIFF'}",
"skip_pages": "{'CONFIRMATION_PAGE', 'SUCCESS_PAGE', 'PAYMENT_PAGE'}",
"url_shortener": 1,
"link_expiry": "date('Y-m-d', strtotime('+14 day'))",
"link_notify": "{'EMAIL'}"
}
}", null, "application/json");
request.Content = content;
var response = client.SendAsync(request).Result;
response.EnsureSuccessStatusCode();
var responseText = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(responseText);
return responseText;
}
public static void Main() {
var testRequest = new TokenizationCreate();
testRequest.check_Tokenization_create_request();
}
}
}Step 2: Directing user to the payment page
The generated payment link can be provided to user through following ways as per your desired payment process:
a) By email:Send the payment link to customer by email. This should be done on your side.
Novalnet will share the generated link to the corresponding end-customer directly via email (specified in the customer.email parameter) based on the hosted_page.link_notify parameter.
Redirecting the end-user to the payment page immediately after payment link generation through header redirect.
<?php
// Handle Redirection
if(!empty($response->result->redirect_url)
&& !empty($response->transaction->txn_secret)) {
$_SESSION['novalnet_txn_secret'] = $response->transaction->txn_secret;
header('Location: ' . $response->result->redirect_url);
exit;
}
?>Step 3: Receiving / Handling payment status
You can use following options to receive and handle the payment status as per your process flow and requirements.
a) Notification / Web hook URL
The notification URL is called from Novalnet server for all transactions including success, rejected, failure and follow-up transactions (return debit, chargeback, incoming credit, refund, subscription extension, etc.).
Please refer this section >>Webhooks Notification<< to setup the Webhooks Notification
To use this option, in the initial pay by link generation request (refer Step 1 above), the parameter transaction.hook_url value had to be passed with the correct url as per your requirement, where you want to set the web hook. And we also provides support in authenticating the webhook notifications, as detailed in this >>link<<
b) Return URL (landing page after payment completion)
On completion of payment the user will be redirected to the given transaction.return_url passed in the initial pay by link generation request (refer Step 1 above).
To use this option, in the initial pay by link generation request (refer Step 1 above), the transaction.return_url and the transaction.error_return_url parameter values had to be passed with the correct url values as per your requirement, where you want to redirect the user after the payment.
Authenticating the redirection response
It is highly recommended that the payment response reaching to your return_url's should be authenticated. To authenticate the redirection response, the previously stored txn_secret is required.
The authentication is made by the comparison against the checksum received in the redirection response. Here you need to re-generate your own checksum value. Below you could find the necessary steps,
- Check if the txn_secret and checksum parameter has been received in the redirection response.
- Build a token string by concatenating the request parameters tid, txn_secret, status and the string reverse of your payment access key.
- Generate your own checksum by using the SHA256 hashing over the token string.
- Compares the checksum received in the redirection response with the generated checksum.
- If the checksum matches, then the authentication is successful else there could be a possible manipulation in the data.
<?php
$txn_secret = !empty($_SESSION["novalnet_txn_secret"])
? $_SESSION["novalnet_txn_secret"]
: $_REQUEST["txn_secret"];
// Handle Response
if (
!empty($_REQUEST["checksum"]) &&
!empty($_REQUEST["tid"]) &&
$txn_secret &&
!empty($_REQUEST["status"])
) {
$token_string = $_REQUEST["tid"] . $txn_secret . $_REQUEST["status"] . strrev("YOUR_PAYMENT_ACCESS_KEY");
$generated_checksum = hash("sha256", $token_string);
if ($generated_checksum !== $_REQUEST["checksum"]) {
echo "While redirecting some data has been changed. The hash check failed";
exit();
} else {
// Handle further process here for the successful scenario
}
} else {
// Could be a handling for the direct payment
}
?>Retrieving all the transaction details (optional)
If you are already handling the webhook process, this step is not required because your webhook receives all the transaction details.
The Transaction response will give you only the minimum details about the transaction, to retrieve entire transaction details, make the /transaction/details API by using the tid returned in the response from Step 2
To know more about the parameters, sample codes and results for retrieving the transaction details API, refer to this >>Link<<
Using Novalnet Admin Portal
- Log in to your Novalnet Admin Portal
- Select the Pay By Link -> Create option under the Payment tab from the Manual Processing menu.
- Fill in the form with your payment details. This includes the amount to be paid, currency, customer details and any other relevant information. and click the Create Payment Link button.
- After confirming the popup, the payment link has been successfully created. You will find the payment link in the popup and the customer will receive the payment link via email if the option is selected in the payment form.
After following these steps, you should have successfully created a payment link via the Novalnet admin portal. You can then share this link with your customers via Manual/Automatic to allow them to make payments easily.
Option 1. Create payment link using existing transaction/customer
Option 2. Create payment link with new entry
Using automated batch processing
This process is chosen whether you prefer this process or if there are difficulties in setting up the real-time API communications from your server to Novalnet. You can configure your SFTP server details in the Novalnet admin portal(Manual processing -> Payment Processing via Batchfiles (SFTP)), through which the payment links can be executed at Novalnet via CSV batch files.
- CSV files (Payment link creation)
- Automated report files from Novalnet along with status and other details:
CSV files are created for executing payment link creation and placed on your SFTP server. Refer sample CSV file https://sandboxdeveloper.novalnet.com/docs/?file=Sample_Batch_File.csv
Novalnet provides automated report output in file formats (CSV) to your SFTP server as predefined. These files can then be parsed and imported into your system as required.