Ce contenu n’est pas encore disponible dans votre langue.
import base64import hashlibimport jsonimport osimport time
import requests
def canonical_json(payload): encoded = json.dumps( payload, ensure_ascii=False, separators=(',', ':'), allow_nan=False, ) escaped = [] for character in encoded: codepoint = ord(character) if character == '/': escaped.append(r'\/') elif codepoint < 0x80: escaped.append(character) elif codepoint <= 0xFFFF: escaped.append(f'\\u{codepoint:04x}') else: codepoint -= 0x10000 escaped.append(f'\\u{0xD800 + (codepoint >> 10):04x}') escaped.append(f'\\u{0xDC00 + (codepoint & 0x3FF):04x}') return ''.join(escaped)
def legacy_sign(body, api_key): payload_base64 = base64.b64encode(body.encode('utf-8')).decode('ascii') return hashlib.md5((payload_base64 + api_key).encode('utf-8')).hexdigest()
merchant_id = os.environ['COINSSEND_MERCHANT_ID']api_key = os.environ['COINSSEND_API_KEY']payload = { 'order_id': f'order_{int(time.time())}', 'amount': '100.50', 'is_customer_fee': False, 'is_customer_network_fee': False, 'allow_card_payments': True, 'success_url': 'https://merchant.example/payment-success', 'cancel_url': 'https://merchant.example/payment-cancelled',}body = canonical_json(payload)
response = requests.post( 'https://api.coinssend.com/v1/invoices', headers={ 'Content-Type': 'application/json', 'Merchant': merchant_id, 'Sign': legacy_sign(body, api_key), }, data=body, timeout=15,)result = response.json()
if not response.ok: raise RuntimeError(result.get('error') or result.get('message') or f'HTTP {response.status_code}')
print(result['data']['code'], result['data']['url'])Use data=body, not json=payload: the canonical string is both the signed
payload and the sent body. Persist the returned identifiers. A duplicate
order_id returns 409 without replaying the original response.