Regular Plan
Introduction
PortOne API payment requests are signed to ensure their authenticity and integrity. This document provides guidelines on how to generate signature for a regular plan request.
Steps
To generate a signature for a regular plan request, follow these steps:
- Concatenate the required parameters of the request into a single string in alphabetical order.
- Calculate the SHA-256 hash of the resulting string.
- Base64-encode the hash to obtain the signature.
Code Examples
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"fmt"
"net/url"
"strconv"
)
type RequestObj struct {
Amount float64
ClientKey string
Currency string
Frequency int64
MerchantOrderRef string
}
func GenerateSignature(requestObj RequestObj, portOneSecret string) string {
// Create a url.Values map and add the necessary parameters
params := make(url.Values)
params.Add("amount", strconv.FormatFloat(requestObj.Amount, 'f', -1, 64))
params.Add("client_key", requestObj.ClientKey)
params.Add("currency", requestObj.Currency)
params.Add("frequency", strconv.Itoa(int(requestObj.Frequency)))
params.Add("merchant_order_ref", requestObj.MerchantOrderRef)
// Encode the parameters
data := params.Encode()
// fmt.Println("data is:", data)
// Create the HMAC hash using SHA-256
secret := []byte(portOneSecret)
message := []byte(data)
hash := hmac.New(sha256.New, secret)
hash.Write(message)
// Convert the hash to a base64 string
hashValue := base64.StdEncoding.EncodeToString(hash.Sum(nil))
return hashValue
}
func main() {
portOneKey := "PORTONE_KEY"
portOneSecret := "PORTONE_SECRET"
// The unique merchant order reference generated by the merchant
merchantOrderRef := ""
requestObj := RequestObj{
Amount: 100.00,
ClientKey: portOneKey,
Currency: "USD",
Frequency: 12,
MerchantOrderRef: merchantOrderRef,
}
// Generate the signature
signature := GenerateSignature(requestObj, portOneSecret)
// Output the signature
fmt.Println("Signature is:", signature)
}
<?php
function GenerateSignature($requestObj, $secretKey) {
$data = array(
'amount' => $requestObj->Amount,
'client_key' => $requestObj->ClientKey,
'currency' => $requestObj->Currency,
'frequency' => $requestObj->Frequency,
'merchant_order_ref' => $requestObj->MerchantOrderRef
);
ksort($data);
$data = http_build_query($data);
$message = $data;
return base64_encode(hash_hmac('sha256', $message, $secretKey, true));
}
function main() {
$key = "PORTONE_KEY";
$secret_key = "PORTONE_SECRET";
// The unique merchant order reference generated by the merchant
$merchant_order_ref = "";
// Example request object
$requestObj = (object) [
'Amount' => 100.00,
'ClientKey' => $key,
'Currency' => 'USD',
'Frequency' => 12,
'MerchantOrderRef' => $merchant_order_ref
];
$signature = GenerateSignature($requestObj, $secret_key);
echo "Signature: " . $signature;
}
main();
?>
const crypto = require('crypto');
const { URLSearchParams } = require('url');
function GenerateSignature(requestObj, secretKey) {
const params = new URLSearchParams();
params.append('amount', requestObj.Amount);
params.append('client_key', requestObj.ClientKey);
params.append('currency', requestObj.Currency);
params.append('frequency', requestObj.Frequency);
params.append('merchant_order_ref', requestObj.MerchantOrderRef);
params.sort();
const message = params.toString();
const hashValue = crypto.createHmac('sha256', secretKey).update(message).digest('base64');
return hashValue;
}
const clientKey = 'PORTONE_KEY';
const secretKey = 'PORTONE_SECRET';
// The unique merchant order reference generated by the merchant
const merchantOrderRef = '';
const requestObj = {
Amount: 100.00,
ClientKey: clientKey,
Currency: 'USD',
Frequency: 12,
MerchantOrderRef: merchantOrderRef
};
const signature = GenerateSignature(requestObj, secretKey);
console.log(`Signature: ${signature}\n`);
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
namespace ConsoleApp
{
class PaymentRequest
{
public double Amount;
public string ClientKey;
public string Currency;
public int Frequency;
public string MerchantOrderRef;
}
class ApiSecurityExample
{
public static string GenerateSignature(PaymentRequest paymentRequest, string secret)
{
var map = new SortedDictionary<string, string>()
{
{ "amount", RemoveTrailingZeros(paymentRequest.Amount) },
{ "client_key", paymentRequest.ClientKey },
{ "currency", paymentRequest.Currency },
{ "frequency", paymentRequest.Frequency.ToString() },
{ "merchant_order_ref", paymentRequest.MerchantOrderRef }
};
var stringBuilder = new StringBuilder();
foreach (var key in map.Keys)
{
if (stringBuilder.Length > 0)
{
stringBuilder.Append("&");
}
var value = map[key];
try
{
stringBuilder.Append((key != null ? Uri.EscapeDataString(key) : ""));
stringBuilder.Append("=");
stringBuilder.Append(value != null ? Uri.EscapeDataString(value) : "");
}
catch (ArgumentNullException e)
{
throw new Exception("The key or value is null.", e);
}
catch (UriFormatException e)
{
throw new Exception("Invalid format for key or value.", e);
}
}
var message = stringBuilder.ToString();
// Console.WriteLine("message: " + message);
var encoding = new ASCIIEncoding();
byte[] keyByte = encoding.GetBytes(secret);
byte[] messageBytes = encoding.GetBytes(message);
var hmacsha256 = new HMACSHA256(keyByte);
byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
string hash_value = Convert.ToBase64String(hashmessage);
return hash_value;
}
private static string RemoveTrailingZeros(double amount)
{
return amount.ToString("0.###################");
}
}
class Program
{
static void Main(string[] args)
{
string key = "PORTONE_KEY";
string secret = "PORTONE_SECRET";
// The unique merchant order reference generated by the merchant
string merchantOrderRef = "";
PaymentRequest paymentRequest = new PaymentRequest()
{
Amount = 100.00,
ClientKey = key,
Currency = "USD",
Frequency = 12,
MerchantOrderRef = merchantOrderRef
};
string signature = ApiSecurityExample.GenerateSignature(paymentRequest, secret);
Console.WriteLine("Signature: " + signature);
}
}
}
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.text.DecimalFormat;
import java.util.Map;
import java.util.TreeMap;
public class Main {
public static void main(String[] args) {
String key = "PORTONE_KEY";
String secret = "PORTONE_SECRET";
// The unique merchant order reference generated by the merchant
String merchantOrderRef = "";
String currency = "USD";
Double amount = 100.00;
// Create an instance of RequestObj using the default constructor
RequestObj requestObj = new RequestObj();
// Use setter methods to set the values
requestObj.setAmount(amount);
requestObj.setClientKey(key);
requestObj.setCurrency(currency);
requestObj.setFrequency(12);
requestObj.setMerchantOrderRef(merchantOrderRef);
String signature = generateSignature(requestObj, secret);
System.out.println("Signature: " + signature);
}
public static String generateSignature(RequestObj requestObj, String secretKey) {
try {
Map<String, String> params = new TreeMap<>();
params.put("amount", requestObj.getAmount());
params.put("client_key", requestObj.getClientKey());
params.put("currency", requestObj.getCurrency());
params.put("frequency", requestObj.getFrequency().toString());
params.put("merchant_order_ref", requestObj.getMerchantOrderRef());
// Encode the parameters
String data = encodeParams(params);
// System.out.println("data: " + data);
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256");
sha256_HMAC.init(secretKeySpec);
byte[] hash = sha256_HMAC.doFinal(data.getBytes());
return Base64.getEncoder().encodeToString(hash);
} catch (Exception e) {
throw new RuntimeException("Failed to calculate hmac-sha256", e);
}
}
public static String encodeParams(Map<String, String> params) {
StringBuilder encodedParams = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
if (encodedParams.length() > 0) {
encodedParams.append("&");
}
encodedParams.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8))
.append("=")
.append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8));
}
return encodedParams.toString();
}
}
class RequestObj {
private Double amount;
private String clientKey;
private String currency;
private Integer frequency;
private String merchantOrderRef;
// Default constructor
public RequestObj() {
}
// Setter methods
public void setClientKey(String clientKey) {
this.clientKey = clientKey;
}
public void setCurrency(String currency) {
this.currency = currency;
}
public void setAmount(Double amount) {
this.amount = amount;
}
public void setMerchantOrderRef(String merchantOrderRef) {
this.merchantOrderRef = merchantOrderRef;
}
public void setFrequency(Integer frequency) {
this.frequency = frequency;
}
// Getter methods
public String getClientKey() {
return clientKey;
}
public String getCurrency() {
return currency;
}
public String getAmount() {
DecimalFormat df = new DecimalFormat("0.##");
return df.format(amount);
}
public String getMerchantOrderRef() {
return merchantOrderRef;
}
public Integer getFrequency() {
return frequency;
}
}
#!/usr/bin/python
# -*- coding: utf-8 -*-
import urllib.parse
import hashlib
import hmac
import base64
class RequestObj:
def __init__(self, Amount, ClientKey, Currency, Frequency, MerchantOrderRef):
# Instance Variables
self.Amount = Amount
self.ClientKey = ClientKey
self.Currency = Currency
self.Frequency = Frequency
self.MerchantOrderRef = MerchantOrderRef
def GenerateSignature(requestObj, secretKey):
f = {
'amount': f"{requestObj.Amount:.2f}".rstrip('0').rstrip('.'),
'client_key': requestObj.ClientKey,
'currency': requestObj.Currency,
'frequency': requestObj.Frequency,
'merchant_order_ref': requestObj.MerchantOrderRef
}
f = dict(sorted(f.items()))
message1 = urllib.parse.urlencode(f)
message = message1.encode('utf-8')
# print(f'message: {message}\n')
secret = secretKey.encode('utf-8')
signature = base64.b64encode(hmac.new(secret, message, digestmod=hashlib.sha256).digest()).decode('utf-8')
return signature
# Define constants
key = 'PORTONE_KEY'
secret = 'PORTONE_SECRET'
# The unique merchant order reference generated by the merchant
merchantOrderRef = ''
# Create an instance of RequestObj
requestObj = RequestObj(
Amount=100.00,
ClientKey=key,
Currency='USD',
Frequency=12,
MerchantOrderRef=merchantOrderRef
)
# Call GenerateSignature
signature = GenerateSignature(requestObj, secret)
print(f'Signature: {signature}\n')
Parameter list to generate signature
amount
amount
float64
The amount of the plan
client_key
client_key
string
The PortOne key of the merchant
currency
currency
string
The currency of the plan
frequency
frequency
string
The frequency of the plan
merchant_order_ref
merchant_order_ref
string
Order Reference sent by merchant to create the plan
Note
Refer to Plan Request for the complete list of plan request parameters.
Updated about 1 month ago