В данном примере рассматривается процесс формирования ссылки на оплату, исходя из предоставленных параметров. При переходе по данной ссылке плательщик будет перенаправлен на страницу оплаты для завершения транзакции.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
import base64 import json import requests # Доступы к Paykeeper server = 'https://xxxxxxx.server.paykeeper.ru' user = 'admin' password = 'xxxxxxx' # Данные клиента email = '' phone = '' # Номер заказа order_id = 9999 # Массив товаров в заказе basket = [ { 'name': 'Тортилья, 20 см, 756 г', 'count': 5, 'price': 381.0, }, ] # Собираем массив товаров для Paykeeper total = 0 prods = [] for row in basket: sum = row['price'] * row['count'] total += sum prods.append({ 'name': row['name'], 'price': row['price'], 'quantity': row['count'], 'sum': sum, 'tax': 'none', 'item_type': 'goods', }) # Добавляем доставку delivery = { 'name': 'Доставка', 'price': 300, 'quantity': 1, 'sum': 300, 'tax': 'none', 'item_type': 'service', } prods.append(delivery) total += delivery['sum'] # Авторизация в Paykeeper credentials = base64.b64encode(f'{user}:{password}'.encode()).decode() headers = { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': f'Basic {credentials}', } # Получение токена def get_token(): url = f'{server}/info/settings/token/' response = requests.get(url, headers=headers) return response.json() # Создание счета def create_invoice(token): payment_data = { 'pay_amount': total, 'orderid': order_id, 'service_name': f';PKC|{json.dumps(prods)}|', 'client_email': email, 'client_phone': phone, 'token': token, } url = f'{server}/change/invoice/preview/' response = requests.post(url, headers=headers, data=payment_data) return response.json() # Основной процесс def main(): try: token_response = get_token() if 'token' in token_response: token = token_response['token'] invoice_response = create_invoice(token) if 'invoice_id' in invoice_response: invoice_id = invoice_response['invoice_id'] link = f'{server}/bill/{invoice_id}/' print(f'Перейдите по ссылке: {link}') else: print(f'Ошибка при создании счета: {invoice_response}') else: print(f'Ошибка авторизации: {token_response}') except Exception as error: print(f'Ошибка: {error}') if __name__ == '__main__': main() |
После перехода по ссылке {link} пользователь будет направлен на страницу оплаты.
На языке Python обработку запросов от PayKeeper об успешных платежах можно реализовать следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
from flask import Flask, request import hashlib app = Flask(__name__) # Ваш секретный ключ SECRET_SEED = "verysecretseed" def calculate_md5(value): return hashlib.md5(value.encode('utf-8')).hexdigest() @app.route('/payment_notification', methods=['POST']) def payment_notification(): # Извлечение данных из запроса id = request.form.get('id', '') # Пример 123 sum = request.form.get('sum', '0.00') # Пример 1500.00 client_id = request.form.get('clientid', '') # Необязательный параметр, пример Иванов Иван order_id = request.form.get('orderid', '') # Необязательный параметр, пример 456 key = request.form.get('key', '') # Пример 2ba28d39e3836f4cc1bd96559417b4fb # Проверка наличия минимально требуемых параметров if not id or not sum or not key: return "Error! Missing or invalid parameters!", 200 try: # Приводим сумму к формату с двумя знаками после запятой sum = f"{float(sum):.2f}" except ValueError: return "Error! Invalid sum format!", 200 # Здесь можно добавить сравнение суммы заказа и переданной суммы sum # Вычисление ожидаемого ключа expected_key = calculate_md5(f"{id}{sum}{client_id}{order_id}{SECRET_SEED}") # Сравнение ключей if key != expected_key: return "Error! Hash mismatch!", 200 # Если хэш совпадает, формируем ответный хэш response_hash = calculate_md5(f"{id}{SECRET_SEED}") return f"OK {response_hash}", 200 if __name__ == "__main__": app.run(port=8080) |
Полный перечень параметров в POST-оповещении можно посмотреть здесь.
В ответ на данный запрос должна быть отправлена строка вида:
Важно отметить, что ответ данного скрипта должен быть исключительно в указанном формате и ни байтом больше, в противном случае PayKeeper будет считать, что ваш сайт неправильно обработал оповещение об успешном платеже.
В PayKeeper возможен полный возврат платежа с помощью метода /change/payment/reverse/. Возврат могут делать только пользователи с включённой функцией возврата. Подробнее можно ознакомиться в документации JSON API. Пример запроса на полный возврат:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
import base64 import json import requests from urllib.parse import urlencode # Номер платежа invoice_id = '1234567890' # Доступы к Paykeeper server = 'https://xxxxxxx.paykeeper.ru' user = 'admin' password = 'xxxxxxx' # Авторизация в Paykeeper credentials = f"{user}:{password}" base64_credentials = base64.b64encode(credentials.encode()).decode() headers = { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': f'Basic {base64_credentials}', } # Функция для выполнения HTTP-запроса def http_request(url, method, headers, data=None): response = None if method == 'GET': response = requests.get(url, headers=headers) elif method == 'POST': response = requests.post(url, headers=headers, data=data) response.raise_for_status() return response.json() # Получение информации о платеже try: url = f'{server}/info/invoice/byid/?id={invoice_id}' response = http_request(url, 'GET', headers) if 'paymentid' in response: # Запрос токена url = f'{server}/info/settings/token/' token_response = http_request(url, 'GET', headers) if 'token' in token_response: # Запрос на возврат платежа request_data = urlencode({ 'id': response['paymentid'], 'amount': 500, 'partial': False, 'token': token_response['token'], }) url = f'{server}/change/payment/reverse/' reverse_response = http_request(url, 'POST', headers, request_data) print(reverse_response) else: print('Не удалось получить токен') else: print('Платеж не найден') except requests.exceptions.RequestException as e: print(f'Ошибка: {e}') |
Менеджер перезвонит вам и расскажет про детали подключения