Authorization
Outgoing Requests
To verify all outgoing requests, you need to perform several steps.
- Form the
bodyobject of the request. - Add the
publicKeyfield to the object — the public key issued by FirstPay. - Sort the keys of this object alphabetically.
- Construct a string in the format:
key=value1|key2=value2|key3=value3. - Encode the resulting string in base64.
- Sign the encoded string using the merchant’s private key with the SHA256 algorithm.
- Convert the signature to base64.
- Add the field
hashto the original request object, assigning it the base64-encoded signature. - The request is now ready to be sent.
Example TypeScript code:
import {
createSign,
} from 'crypto';
const publicKey = '';
const privateKey = '';
function prepareMessage(message: IObject): string {
const res = Object
.keys(message)
.sort()
.map((key) => `${key}=${message[key]}`)
.join('|');
return Buffer.from(res).toString('base64');
}
function getSignedHash(message: IObject, privateKey: string): string {
const preparedMessage = prepareMessage(message);
const preparedPrivateKey = Buffer.from(privateKey, 'utf-8');
return createSign('SHA256')
.update(preparedMessage, 'base64')
.sign(preparedPrivateKey, 'base64');
}
const requestBody = {};
requestBody.publicKey = publicKey;
requestBody.hash = getSignedHash(requestBody, privateKey);
// Send request
Incoming Requests
To verify all incoming requests, perform the following steps:
- Check for the presence of the
hashfield. - Separate the request
bodyfrom thehashfield. - Verify the hash field using the remaining object and FirstPay’s public key.
- Prepare the object following steps 3-5 from the previous section (stringify, base64 encode).
- Verify the
hashvalue using the SHA256 algorithm.
import {
createVerify,
} from 'crypto';
const publicKey = '';
const privateKey = '';
function prepareMessage(message: IObject): string {
const res = Object
.keys(message)
.sort()
.map((key) => `${key}=${message[key]}`)
.join('|');
return Buffer.from(res).toString('base64');
}
function verifySignedHash(message: IObject, signedHash: string, publicKey: string): boolean {
const preparedMessage = Crypto.prepareMessage(message);
return createVerify('SHA256')
.update(preparedMessage, 'base64')
.verify(publicKey, signedHash, 'base64');
}
const requestBody = {};
if (!requestBody.hash) {
console.log('No hash');
}
const {hash, ...restBody} = requestBody;
if (!verifySignedHash(restBody, hash, publicKey)) {
console.log('Invalid signature');
}
// Do something