Tarlanpayments
Рус
Рус
  • Платежный шлюз
    • Общая информация
      • Процесс одностадийного платежа
      • Процесс двухстадийного платежа
      • Виды операций
      • 3D-Secure
      • PCI DSS
    • Типы транзакций
    • Структура ответов системы
    • Коды ошибок
    • Статусы транзакций
    • Формирование подписи
    • Дополнительные параметры
    • Взаимодействие с формой оплаты
      • Инициация приёма денежных средств
      • Инициация вывода денежных средств
      • Привязка карты
      • Инициация приёма денежных средств посредством Apple Pay
      • Инициация приёма денежных средств посредство Google Pay
      • Iframe
    • Платежи без формы оплаты
      • Платеж по сохраненной карте (one click)
      • Вывод денежных средств (pay-out)
      • Шифрование платежной карты
    • Вспомогательные методы
      • Удаление привязанной карты
      • Проверка статуса транзакции
      • Получение списка карт
      • Возврат платежа
      • Расчет верхней комиссии
      • Подтверждение списания средств
      • Отмена списания средств
    • Webhook платежной системы
      • Статус оплаты
      • Готовность проведения оплаты
    • Smart Pay
      • Google pay
    • CMS
      • WordPress
      • Bitrix
      • Tilda
    • Сводка изменений
  • AGWS
    • Коды состояния аккаунта
    • Статусы транзакции
    • Коды ошибок
    • Причина отклонения операции
    • Время жизни транзакции
    • Формирование подписи
    • Проверка состояния аккаунта
    • Проведение платежа
    • Проверка статуса пополнения
    • Проверка остатка баланса на счету
    • Подтверждение списания средств
    • Создание ссылки на оплату
    • Информация по услугам
    • Получение информации о юзере
    • Callback платежной системы
  • Получение фискального чека
  • Расчет верхней комиссии
Powered by GitBook
On this page
  1. Платежный шлюз
  2. Платежи без формы оплаты

Шифрование платежной карты

Last updated 9 months ago

В целях обеспечения безопасности данные платежной карты шифруются с использованием RSA PKCS1

Для шифрования необходимо:

  1. Запрос GET Запрос GET для получения publick_key с помощью которого шифруются данные карт используя алгоритм RSA PKCS1

  2. Формируем JSON. Для приема денежных средств необходимы все данные карты: {"pan":"4049121234345656","exp_month":"04","exp_year":"26","cvc":"123","full_name":"Test test"} Для вывод денежных средств необходимы только pan карты: {"pan":"4049121234345656"}

  3. Шифруем получившийся объект используя алгоритм RSA PKCS1 и публичный ключ

  4. Получившийся шифр кодируем в base64

Пример ответа GET

{
  "status": true,
  "message": "Success",
  "result": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxTl2VCVIQ3R6WWexWfEt\n80+mwQLOwVRSsmmoFZhYnuCgtdthJlb4CJ+LTup19ttHdU0h43r3W4urNDWWFuxf\nlKsIuuztP4Zc44TV4gG7YkHmz+iP90JrYzhE4yMaMYv0jTJ1lXBGTHk+Sfoa2nGg\nIdB/onVGfX27W7yjv62yZ/7V/GZljxP/8V3x/KRm/i05B4hsSE3DWw2AX+dOtvSj\n/JYXu713nGh4lsj9/CABT/GHkwY33e14YwXAS4P7f/ixGdcFudKU1QxIorFqOK0W\nDURmfnnoBuL1ailkHWb8LIu7FXUEbKi0QpmKsV5UnFWNuIQKtE/Mt+P6UJ/oGtdc\nHQIDAQAB\n-----END PUBLIC KEY-----"
}
<?php
function encryptCard($pan) {
    $panData = json_encode(['pan' => $pan]);

    // Получаем публичный ключ
    $response = file_get_contents('https://prapi.tarlanpayments.kz/card/api/v1/encryption/public-key');
    if ($response === FALSE) {
        throw new Exception('Can not get public key');
    }

    $responseJson = json_decode($response, true);
    if (!isset($responseJson['result'])) {
        throw new Exception('Invalid response format');
    }

    $publicKeyPem = $responseJson['result'];

    // Декодируем публичный ключ из формата PEM
    $publicKey = openssl_pkey_get_public($publicKeyPem);
    if ($publicKey === FALSE) {
        throw new Exception('Failed to parse public key');
    }

    // Шифруем данные с использованием публичного ключа
    $encryptedCard = '';
    if (!openssl_public_encrypt($panData, $encryptedCard, $publicKey)) {
        throw new Exception('Failed to encrypt data');
    }

    // Возвращаем зашифрованную строку в формате base64
    return base64_encode($encryptedCard);
}

try {
    $pan = '4049121234345656'; // Пример PAN, который можно заменить на любой другой
    $encryptedCard = encryptCard($pan);
    echo "Encrypted Card: " . $encryptedCard . PHP_EOL;
} catch (Exception $e) {
    echo "Error: " . $e->getMessage() . PHP_EOL;
}
?>
import requests
import json
import base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_PKCS1_v1_5
from Crypto.Random import get_random_bytes

def encrypt_card(pan):
    pan_data = json.dumps({'pan': pan}).encode('utf-8')

    # Получаем публичный ключ
    response = requests.get('https://prapi.tarlanpayments.kz/card/api/v1/encryption/public-key')
    if response.status_code != 200:
        raise Exception('Can not get public key')
    
    response_json = response.json()
    if 'result' not in response_json:
        raise Exception('Invalid response format')

    public_key_pem = response_json['result']

    # Декодируем публичный ключ из формата PEM
    public_key = RSA.import_key(public_key_pem)

    # Шифруем данные с использованием публичного ключа
    cipher = Cipher_PKCS1_v1_5.new(public_key)
    encrypted_card = cipher.encrypt(pan_data)

    # Возвращаем зашифрованную строку в формате base64
    return base64.b64encode(encrypted_card).decode('utf-8')

try:
    pan = '4049121234345656' # Пример PAN, который можно заменить на любой другой
    encrypted_card = encrypt_card(pan)
    print("Encrypted Card:", encrypted_card)
except Exception as e:
    print("Error:", str(e))
package main

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"encoding/json"
	"encoding/pem"
	"errors"
	"fmt"
	"io"
	"net/http"
)

func EncryptCard(pan string) (string, error) {
	panData := struct {
		Pan string `json:"pan"`
	}{
		Pan: pan,
	}

	response := struct {
		PublicKey string `json:"result"`
	}{}

	notSortedJson, err := json.Marshal(panData)
	if err != nil {
		return "", err
	}

	publicKeyResp, err := http.Get("https://prapi.tarlanpayments.kz/card/api/v1/encryption/public-key")
	if err != nil {
		return "", err
	}
	defer publicKeyResp.Body.Close()

	if publicKeyResp.StatusCode != http.StatusOK {
		return "", errors.New("can not get public key")
	}

	readAll, err := io.ReadAll(publicKeyResp.Body)
	if err != nil {
		return "", err
	}

	err = json.Unmarshal(readAll, &response)
	if err != nil {
		return "", err
	}

	block, _ := pem.Decode([]byte(response.PublicKey))
	if block == nil || block.Type != "PUBLIC KEY" {
		return "", fmt.Errorf("failed to parse PEM block containing the public key")
	}

	pub, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		return "", fmt.Errorf("failed to parse public key: %v", err)
	}

	rsaPub, ok := pub.(*rsa.PublicKey)
	if !ok {
		return "", fmt.Errorf("not an RSA public key")
	}

	encryptedCard, err := rsa.EncryptPKCS1v15(rand.Reader, rsaPub, notSortedJson)
	if err != nil {
		return "", err
	}

	return base64.StdEncoding.EncodeToString(encryptedCard), nil
}

func main() {
	pan := "4049121234345656" // Пример PAN, который можно заменить на любой другой
	encryptedCard, err := EncryptCard(pan)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	fmt.Println("Encrypted Card:", encryptedCard)
}
Процедура ТестированиеEncryptCard()
    // Пример PAN для тестирования
    PAN = "4049121234345656";
    
    // Вызов функции шифрования
    Попытка
        ЗашифрованнаяКарта = EncryptCard(PAN);
        Сообщить("Зашифрованная карта: " + ЗашифрованнаяКарта);
    Исключение
        Сообщить("Ошибка: " + ОписаниеОшибки());
    КонецПопытки;
КонецПроцедуры

Процедура EncryptCard(PAN)
    // Данные карты
    ДанныеКарты = Новый Структура;
    ДанныеКарты.Вставить("pan", PAN);

    // Преобразование данных карты в JSON
    JSONСтрока = ПреобразованиеВJSON(ДанныеКарты);

    // Получение публичного ключа
    Запрос = Новый HTTPЗапрос("https://prapi.tarlanpayments.kz/card/api/v1/encryption/public-key");
    HTTPСоединение = Новый HTTPСоединение("prapi.tarlanpayments.kz");
    Ответ = HTTPСоединение.Получить(Запрос);

    Если Ответ.КодСостояния <> 200 Тогда
        Сообщить("Ошибка получения публичного ключа: " + Ответ.КодСостояния);
        Возврат "";
    КонецЕсли;

    // Чтение тела ответа
    ТелоОтвета = Ответ.ПолучитьТелоКакСтроку();
    Декодер = Новый JSONДекодер;
    ОтветJSON = Декодер.ПрочитатьJSON(ТелоОтвета);

    ПубличныйКлючСтрока = ОтветJSON.result;

    // Декодирование PEM и извлечение публичного ключа
    ПубличныйКлючБайты = КодировкаBase64.СтрокаВБайты(ПубличныйКлючСтрока);
    ПубличныйКлючPEM = ПолучитьPEM(ПубличныйКлючБайты);

    // Шифрование данных карты
    ЗашифрованнаяКарта = ШифрованиеRSA(ПубличныйКлючPEM, JSONСтрока);

    // Кодирование зашифрованных данных в Base64
    ЗашифрованнаяКартаBase64 = КодировкаBase64.СтрокаИзБайтов(ЗашифрованнаяКарта);

    Возврат ЗашифрованнаяКартаBase64;
КонецПроцедуры

Функция ПреобразованиеВJSON(Данные)
    JSONЗапись = Новый ЗаписьJSON;
    JSONЗапись.УстановитьСтроку();
    JSONЗапись.ЗаписатьЗначение(Данные);
    Возврат JSONЗапись.Закрыть();
КонецФункции

Функция ПолучитьPEM(ПубличныйКлючБайты)
    ОткрытыйКлюч = Новый ОткрытыйКлючШифрования;
    ОткрытыйКлюч.Установить(ПубличныйКлючБайты);
    Возврат ОткрытыйКлюч;
КонецФункции

Функция ШифрованиеRSA(ОткрытыйКлюч, Данные)
    Результат = Новый Массив;
    Для Каждого Байт Из ОткрытыйКлюч.Шифровать(Данные, "RSA/ECB/PKCS1Padding") Цикл
        Результат.Добавить(Байт);
    КонецЦикла;
    Возврат Результат;
КонецФункции
https://prapi.tarlanpayments.kz/card/api/v1/encryption/public-key
https://sandboxapi.tarlanpayments.kz/card/api/v1/encryption/public-key
https://prapi.test-tarlanpayments.kz/card/api/v1/encryption/public-key