Robokassa Создание ссылки без перенаправления на оплату (JWT)
Помогите, пожалуйста, разобраться, что я делаю не так?
Вот документация, на русском, https://docs.robokassa.ru/pay-interface/#jwt
Делаю первый раз такое. Вроде бы всё, как написано делаю, но в ответ получаю {"isSuccess":false,"message":"Некорректно составлен запрос"}
import asyncio
import base64
import hashlib
import hmac
import json
from aiohttp import ClientSession
from pydantic import BaseModel
class InvoiceItemsSchema(BaseModel):
Name: str
Quantity: int
Cost: int
Tax: str = "none"
PaymentMethod: str = "full_prepayment"
PaymentObject: str = "commodity"
class Config:
from_attributes = True
class JWTPayloadSchema(BaseModel):
MerchantLogin: str
InvoiceType: str
Culture: str
InvId: int
OutSum: int
Description: str
MerchantComments: str
InvoiceItems: list[InvoiceItemsSchema]
Shp_id: str
class Config:
from_attributes = True
async def create_payment_link(data):
url = "https://services.robokassa.ru/InvoiceServiceWebApi/api/CreateInvoice"
async with ClientSession() as session:
try:
async with session.post(url, json=data) as resp:
res = await resp.text()
print(res)
return res
except Exception as e:
print(e)
return None
def jwt_encode(data):
json_string = json.dumps(data)
json_bytes = json_string.encode('utf-8')
base64_encoded = base64.b64encode(json_bytes)
base64_url_encoded = base64_encoded.decode('utf-8').replace('+', '-').replace('/', '_').rstrip('=')
return base64_url_encoded
def hmac_encode(data):
shop_id = "some_shop_id"
pass_1 = "some_pass_1"
message = data.encode('utf-8')
key = f"{shop_id}:{pass_1}".encode()
hmac_obj = hmac.new(key=key, msg=message, digestmod=hashlib.md5)
hmac_digest = hmac_obj.digest()
hmac_base64url = base64.urlsafe_b64encode(hmac_digest).decode('utf-8').rstrip('=')
return hmac_base64url
def calculate_signature(*args) -> str:
"""Create signature MD5"""
return hashlib.md5(':'.join(str(arg) for arg in args).encode()).hexdigest()
def create_invoice_items(products: list) -> list[InvoiceItemsSchema]:
result_list = []
for item in products:
i = InvoiceItemsSchema(
Name=item.get('name'),
Quantity=item.get('quantity'),
Cost=item.get('price'),
)
result_list.append(i)
return result_list
def create_jwt_header():
json_data = {"typ": "JWT", "alg": "MD5"}
return jwt_encode(json_data)
def create_jwt_payload(cart: dict, tg_id: str) -> str:
total_sum = cart.get('total_sum')
items = create_invoice_items(cart.get('products'))
inv_items = JWTPayloadSchema(
MerchantLogin="some_merchant_login",
InvoiceType="OneTime",
Culture="ru",
InvId=0,
OutSum=total_sum,
Description="test pay fillatova shop",
MerchantComments=f"покупка от {tg_id}",
InvoiceItems=items,
Shp_id=tg_id
)
json_data = inv_items.model_dump()
result = jwt_encode(json_data)
return result
async def create_jwt_payment(cart: dict, tg_id: str) -> str:
fst_part = create_jwt_header()
snd_part = create_jwt_payload(cart=cart, tg_id=tg_id)
pre_str = f'{fst_part}.{snd_part}'
trd_part = hmac_encode(pre_str)
full_str = f'{fst_part}.{snd_part}.{trd_part}'
result = await create_payment_link(full_str)
return result
exam_cart = {'products': [{'amount': 7000,
'name': 'Продукт 1',
'price': 3500,
'quantity': 2},
{'amount': 3500,
'name': 'Продукт 2',
'price': 3500,
'quantity': 1},
],
'total_sum': 20500}
asyncio.run(create_jwt_payment(cart=exam_cart, tg_id='111'))