-
Notifications
You must be signed in to change notification settings - Fork 8
6. Payments
You can enable in-game purchases using our solutions to accept payments via Telegram Stars.
Any questions? Contact us!
To track successful payments, set up a publicly accessible webhook that accepts POST requests with the specified payload format. For example, this:
{
"hash": "68fa4570ea8134e9381a72b771ea00184db008be5ad98ab9283935653db3cb5d",
"message": null,
"payment": {
"telegramId": 1234567890,
"amount": 10,
"successful": true,
"externalId": order_p_12
}
}
Event types are defined by root keys. Event is received by the endpoint on the backend of the game
hash - event signature.
We use a signature for each event to prevent malicious requests on your webhook endpoints.
You can verify that this event was sent by the original PlayDeck service and the integrity of the data received by comparing the received hash parameter with the hexadecimal representation of the HMAC-SHA-256 signature of the data-check-string with the SHA256 hash of the game_token (provided from our side) used as a secret key.
Data-check-string is a concatenation of all received fields of the object payment , sorted in alphabetical order in the format key= with a line feed character ('\n', 0x0A) used as a separator – e.g.
'amount=<amount>\nexternalId=<externalId>\nsuccessful=<successful>\ntelegramId=<telegramId>'
The full check might look like this:
data_check_string = ...
secret_key = SHA256(<game_token>)
if (hex(HMAC_SHA256(data_check_string, secret_key)) == hash)
{
// request is valid
}
As a result, for the example event above we get data check string:
"amount=10\nexternalId=order_p_12\nsuccessful=true\ntelegramId=1234567890"
Using the example game_token = hpXXKPbIWT to sign it and get hash=68fa4570ea8134e9381a72b771ea00184db008be5ad98ab9283935653db3cb5d.
All of the data above: request, hash and check string is an example of validation process. When validating the request you received from PlayDeck, hash you got in the event must match the data you received after signing the control check string with the token. This way you can make sure that you received the request exactly from PlayDeck.
Telegram stars is the internal currency of telegram. Payment through it can be made using our wrapper. Please note: the description must be no more than 256 characters, and the amount is greater than 0.
const { parent } = window;
parent.postMessage({ playdeck: { method: 'requestPayment',
value: {"amount": 1, // integer
"description": "your description",
"externalId": "unique order", // Unique order identifier in your system, which you can use to check in postback that payment was successful
"photoUrl": "optional field"} } },'*');
window.addEventListener('message', ({ data }) => {
const playdeck = data?.playdeck;
if (!playdeck) return;
if (playdeck.method === 'requestPayment') {
console.log(playdeck.value); // { url: 'https://t.me/$XIVLvBpfOEsBBwAARs....' } // payment link
}
});
After receiving the link, you can open it using our other method:
const { parent } = window;
parent.postMessage(
{
playdeck: {
method: 'openTelegramLink',
value: 'https://t.me/$XIVLvBpfOEsBBwAARs....',
},
},
'*'
);
You can also track the payment using the getPaymentInfo method. Verification is carried out using the externalId one that was used at the time the payment was created.
const { parent } = window;
parent.postMessage({ playdeck: { method: 'getPaymentInfo', value: { "externalId": number }}},'*');
window.addEventListener('message', ({ data }) => {
const playdeck = data?.playdeck;
if (!playdeck) return;
if (playdeck.method === 'getPaymentInfo') {
console.log(playdeck.value); // PaymentInfo
}
});
The PaymentInfo object looks like this:
interface PaymentInfo {
paid: boolean;
telegramId: number | null;
datetime: number | null;
amount: number | null
}
If externalId order was paid, than paid=true, telegramId=payerTgId, datetime=payTime. Otherwise paid=false, telegramId=null, datetime=null
You can read more about the wrapper and how to use it on the Integration guide