1
|
|
|
from bitpay.bitpay_exceptions import * |
2
|
|
|
import bitpay.bitpay_key_utils as bku |
3
|
|
|
from bitpay.bitpay_client import * |
4
|
|
|
import pprint |
5
|
|
|
import requests |
6
|
|
|
import json |
7
|
|
|
import re |
8
|
|
|
import os.path |
9
|
|
|
|
10
|
|
|
#API_HOST = "https://bitpay.com" #for production, live bitcoin |
11
|
|
|
API_HOST = "https://test.bitpay.com" #for testing, testnet bitcoin |
12
|
|
|
KEY_FILE = "/tmp/key.priv" |
13
|
|
|
TOKEN_FILE = "/tmp/token.priv" |
14
|
|
|
pp = pprint.PrettyPrinter(indent=4) |
15
|
|
|
|
16
|
|
|
# check if there is a preexisting key file |
17
|
|
|
if os.path.isfile(KEY_FILE): |
18
|
|
|
f = open(KEY_FILE, 'r') |
19
|
|
|
key = f.read() |
20
|
|
|
f.close() |
21
|
|
|
print("Creating a bitpay client using existing private key from disk.") |
22
|
|
|
else: |
23
|
|
|
key = bku.generate_pem() |
24
|
|
|
f = open(KEY_FILE, 'w') |
25
|
|
|
f.write(key) |
26
|
|
|
f.close() |
27
|
|
|
|
28
|
|
|
client = Client(API_HOST, False, key) |
29
|
|
|
|
30
|
|
View Code Duplication |
def fetch_token(facade): |
|
|
|
|
31
|
|
|
if os.path.isfile(TOKEN_FILE + facade): |
32
|
|
|
f = open(TOKEN_FILE + facade, 'r') |
33
|
|
|
token = f.read() |
34
|
|
|
f.close() |
35
|
|
|
print("Reading " + facade + " token from disk.") |
36
|
|
|
client.tokens[facade] = token |
37
|
|
|
else: |
38
|
|
|
pairingCode = client.create_token(facade) |
39
|
|
|
print("Creating " + facade + " token.") |
40
|
|
|
print("Please go to: %s/dashboard/merchant/api-tokens then enter \"%s\" then click the \"Find\" button, then click \"Approve\"" % (API_HOST, pairingCode)) |
41
|
|
|
raw_input("When you've complete the above, hit enter to continue...") |
42
|
|
|
print("token is: %s" % client.tokens[facade]) |
43
|
|
|
f = open(TOKEN_FILE + facade, 'w') |
44
|
|
|
f.write(client.tokens[facade]) |
45
|
|
|
f.close() |
46
|
|
|
|
47
|
|
View Code Duplication |
def get_from_bitpay_api(client, uri, token): |
|
|
|
|
48
|
|
|
payload = "?token=%s" % token |
49
|
|
|
xidentity = bku.get_compressed_public_key_from_pem(client.pem) |
50
|
|
|
xsignature = bku.sign(uri + payload, client.pem) |
51
|
|
|
headers = {"content-type": "application/json", |
52
|
|
|
"X-Identity": xidentity, |
53
|
|
|
"X-Signature": xsignature, "X-accept-version": "2.0.0"} |
54
|
|
|
try: |
55
|
|
|
pp.pprint(headers) |
56
|
|
|
print(uri + payload) |
57
|
|
|
response = requests.get(uri + payload, headers=headers, verify=client.verify) |
58
|
|
|
except Exception as pro: |
59
|
|
|
raise BitPayConnectionError(pro.args) |
60
|
|
|
if response.ok: |
61
|
|
|
return response.json()['data'] |
62
|
|
|
client.response_error(response) |
63
|
|
|
|
64
|
|
|
""" |
65
|
|
|
POST to any resource |
66
|
|
|
Make sure to include the proper token in the params |
67
|
|
|
""" |
68
|
|
View Code Duplication |
def post_to_bitpay_api(client, uri, resource, params): |
|
|
|
|
69
|
|
|
payload = json.dumps(params) |
70
|
|
|
uri = uri + "/" + resource |
71
|
|
|
xidentity = key_utils.get_compressed_public_key_from_pem(client.pem) |
72
|
|
|
xsignature = key_utils.sign(uri + payload, client.pem) |
73
|
|
|
headers = {"content-type": "application/json", |
74
|
|
|
"accept": "application/json", "X-Identity": xidentity, |
75
|
|
|
"X-Signature": xsignature, "X-accept-version": "2.0.0"} |
76
|
|
|
try: |
77
|
|
|
response = requests.post(uri, data=payload, headers=headers, |
78
|
|
|
verify=client.verify) |
79
|
|
|
except Exception as pro: |
80
|
|
|
raise BitPayConnectionError(pro.args) |
81
|
|
|
if response.ok: |
82
|
|
|
return response.json()['data'] |
83
|
|
|
client.response_error(response) |
84
|
|
|
|
85
|
|
|
""" |
86
|
|
|
DELETE to any resource |
87
|
|
|
Make sure to include the proper token in the params |
88
|
|
|
""" |
89
|
|
View Code Duplication |
def delete_from_bitpay_api(client, uri, token): |
|
|
|
|
90
|
|
|
payload = "?token=%s" % token |
91
|
|
|
xidentity = bku.get_compressed_public_key_from_pem(client.pem) |
92
|
|
|
xsignature = bku.sign(uri + payload, client.pem) |
93
|
|
|
headers = {"content-type": "application/json", |
94
|
|
|
"X-Identity": xidentity, |
95
|
|
|
"X-Signature": xsignature, "X-accept-version": "2.0.0"} |
96
|
|
|
try: |
97
|
|
|
pp.pprint(headers) |
98
|
|
|
print(uri + payload) |
99
|
|
|
response = requests.delete(uri + payload, headers=headers, verify=client.verify) |
100
|
|
|
except Exception as pro: |
101
|
|
|
raise BitPayConnectionError(pro.args) |
102
|
|
|
if response.ok: |
103
|
|
|
return response.json()['data'] |
104
|
|
|
client.response_error(response) |
105
|
|
|
|
106
|
|
|
fetch_token("payroll") |
107
|
|
|
|
108
|
|
|
# Fetch the payroll token |
109
|
|
|
token = client.tokens['payroll'] |
110
|
|
|
print("token = " + token) |
111
|
|
|
|
112
|
|
|
batchId = "C61hxf14PKFWtChQ8Sgcne" |
113
|
|
|
print("Fetch a payout batch") |
114
|
|
|
# GET the payout batch |
115
|
|
|
|
116
|
|
|
payoutBatch = get_from_bitpay_api(client, "https://test.bitpay.com/payouts/"+batchId, token) |
117
|
|
|
pp.pprint(payoutBatch) |
118
|
|
|
|
119
|
|
|
# now use the token received from the GET payout batch to cancel the payout batch |
120
|
|
|
token = payoutBatch["token"] |
121
|
|
|
|
122
|
|
|
print("Deleting payout batch " + batchId) |
123
|
|
|
response = delete_from_bitpay_api(client, "https://test.bitpay.com/payouts/"+batchId, token) |
124
|
|
|
pp.pprint(response) |
125
|
|
|
|
126
|
|
|
|