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'))

Ответы (0 шт):