I accept payments through bitcoinpay.com. In the documentation I ran into an example of a payment verification. Before using this method, I decided to do this in the example. And no matter how hard I tried, it doesn’t work for me to get the same hash that they get. Here is an example from the documentation . But I will bring it here. Example response from server:
{"data": {"status": "pending", "payment_id": "rvnEvs3pzGVlBQaE", "settled_currency": "USD", "server_time": 1438681512, "paid_amount": "0.03545288", "reference": "{\"customer_email\": \"john.doe@example.org\", \"order_number\": 1234, \"customer_name\": \"John Doe\"}", "payment_url": "https://bitcoinpay.com/en/sci/invoice/btc/rvnEvs3pzGVlBQaE/", "price": "10.00", "confirmations": -1, "settled_amount": "6.95", "txid": "", "currency": "USD", "create_time": 1438688711, "item": "Order #1234", "address": "172eh5xbTW9Fu4EvaNZt1ymoUz9pV2snYG", "timeout_time": 1438689611, "paid_currency": "BTC", "description": "Order #1234 description"}}
It is known that callback password is what I understand. QKG7m{dzv32mmYGN
Key - QKG7m{dzv32mmYGN
the hash is calculated from the line like <answer> <password> and get the hash 3ee96c641d5fe230343950839aff469fa7c79b52bfefc5790bb9308ddeab605a
I brought everything to the string and then I calculated the hash, tried it and so on.
j = {"data": {.....}} d = j["data"]
Then I came across other documentation from the same site, where the hash was calculated not from the answer entirely, but from the date section, and the values were sorted by key in alphabetical order. I tried to do as an example above.
import hashlib d = {"status": "pending", "payment_id": "rvnEvs3pzGVlBQaE", "settled_currency": "USD", "server_time": 1438681512, "paid_amount": "0.03545288", "reference": "{\"customer_email\": \"john.doe@example.org\", \"order_number\": 1234, \"customer_name\": \"John Doe\"}", "payment_url": "https://bitcoinpay.com/en/sci/invoice/btc/rvnEvs3pzGVlBQaE/", "price": "10.00", "confirmations": -1, "settled_amount": "6.95", "txid": "", "currency": "USD", "create_time": 1438688711, "item": "Order #1234", "address": "172eh5xbTW9Fu4EvaNZt1ymoUz9pV2snYG", "timeout_time": 1438689611, "paid_currency": "BTC", "description": "Order #1234 description"} a = "QKG7m{dzv32mmYGN" s = "" l = d.keys() l.sort() for c in l: s+=str(d[c]) s +=a h = hashlib.sha256(s).hexdigest() print h
Hash anyway did not match. Tell me how they calculated this hash in the first example? And then I guess how to count it at home. It seems that it is written that the string is from whole data + callback password, but in fact it turns out wrong. Maybe someone already implemented in python? I would be glad to see examples.
PS I came across a ready-made example from a module to some kind of cms, there it looked something like this:
hash('sha256', '$RESPONSE_HTTP' . '$CALLBACK_PASSWORD')
I am not familiar with PHP, but I think that there is a concatenation of the answer with a password and the calculation of the hash.
PPS I tried on a live example (listing below) to count. What is the first, that the second method, the hashes do not converge.
#!/usr/bin/python #--*--coding: utf-8--*-- import json import hashlib from urllib2 import Request, urlopen pwd = "мой_callback_password" login = "zxcv432fg" email = "zxc@dfg.ru" satoshi = 0.001 values = { "settled_currency": "BTC", "return_url": "http://site.ru/buy/thankyou.html", "notify_url": "http://site.ru/cgi-bin/btc/order-received.cgi", "notify_email": "mail@mail.ru", "price": satoshi, "currency": "BTC", "reference": { "customer_name": login, "order_number": 123, "customer_email": email }, "item": "la2coin", "description": "buy la2coin" } data = json.dumps(values) headers = { 'Content-Type': 'application/json', 'Authorization': 'Token мой_ключ_апи' } request = Request('https://www.bitcoinpay.com/api/v1/payment/btc', data=data, headers=headers) response = urlopen(request) response_body = urlopen(request).read() signature = response.info()['BPSignature'] data_validate = response_body + pwd hash_string = hashlib.sha256(data_validate).hexdigest() print "ответ - ", response_body, '\n' print "строка для хеширования - ", data_validate, '\n' print "Хеш с заголовка - ", signature, '\n' print "Рассчитаный хеш - ", hash_string, '\n' if signature == hash_string: print "Validated succesfully!" else: print "Wrong Signature"
j={...}
definitely not suitable. I don’t know how in python, but if the text can be enclosed in single quotes there, then I would doa='{"data": {"status": "pending", ...
i.e. with all the spaces like theirs. well, or somehow screen quotes that would be in one-to-one line of their anonymity - Mike