def get_addrs_from_paymentrequest(pr): ret_list = [] pr_obj = PaymentRequest() pr_obj.ParseFromString(pr) pd = PaymentDetails() pd.ParseFromString(pr_obj.serialized_payment_details) for output in pd.outputs: script = deserialize_script(output.script) if script[0] == OP_DUP and script[1] == OP_HASH160 and script[3] == OP_EQUALVERIFY and script[4] == OP_CHECKSIG: ret_list.append(hex_to_b58check(script[2].encode('hex'))) return ret_list
def create_and_send_payment_message(self, payment_request): pr = PaymentRequest() pr.ParseFromString(payment_request) pd = PaymentDetails() pd.ParseFromString(pr.serialized_payment_details) # Retrieve unique payment_url created by Addressimo and replace with Flask LiveServerTestCase server URL payment_uuid = pd.payment_url.rsplit('/', 1)[1] payment_url = '%s/payment/%s' % (self.get_server_url(), payment_uuid) # Add to payment_uuid Redis cleanup list self.redis_pr_store_cleanup.append(payment_uuid) # Create Payment output to satisfy PaymentRequest priv = sha256('random') ins = [{ 'output': '35d49e1833a20baffae35fb1423427d0c23e83b428a933eebde95ac7fd1c967a:0', 'value': 10000, 'script': 'random_script' }] outs = [{ 'value': pd.outputs[0].amount, 'address': '%s' % script_to_address(pd.outputs[0].script) }] tx = sign(mktx(ins, outs), 0, priv) refund_address = '1CpLXM15vjULK3ZPGUTDMUcGATGR9xGitv' self.payment = Payment() self.payment.merchant_data = pd.merchant_data self.payment.memo = 'Payment memo' self.payment.transactions.append(tx) output = self.payment.refund_to.add() output.amount = pd.outputs[0].amount output.script = serialize_script([ OP_DUP, OP_HASH160, b58check_to_hex(refund_address), OP_EQUALVERIFY, OP_CHECKSIG ]).decode('hex') # Set appropriate headers for Payment headers = { 'Content-Type': 'application/bitcoin-payment', 'Accept': 'application/bitcoin-paymentack', 'Test-Transaction': True } response = requests.post(payment_url, data=self.payment.SerializeToString(), headers=headers) ####################### # Validation ####################### # PaymentRequest data used for Payment Creation self.assertTrue( pd.payment_url.startswith('https://%s/payment/' % config.site_url)) self.assertEqual((33000 * 100000000), pd.outputs[0].amount) self.assertEqual(payment_uuid, pd.merchant_data) # PaymentRequest meta data used later for Payment validation pr_redis = Redis.from_url(config.redis_pr_store) pr_data = pr_redis.hgetall(payment_uuid) self.assertIsNotNone(pr_data.get('expiration_date')) payment_data = json.loads(pr_data.get('payment_validation_data')) self.assertEqual(self.test_id_obj.wallet_address, payment_data.keys()[0]) self.assertEqual((33000 * 100000000), payment_data[self.test_id_obj.wallet_address]) # Payment meta data used for refund endpoint payment_redis = Redis.from_url(config.redis_payment_store) payment_data = payment_redis.hgetall('testtxhash') self.assertIsNotNone(payment_data.get('expiration_date')) self.assertEqual('Payment memo', payment_data.get('memo')) self.assertEqual( "['76a914819d3b204b99f252da2ef21293c621e75dd1444f88ac']", payment_data.get('refund_to')) return response
def add(): resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type) id_obj = resolver.get_id_obj(get_id()) if not id_obj: return create_json_response(False, 'Invalid Identifier', 404) rdata = None try: rdata = request.get_json() except Exception as e: log.warn("Exception Parsing JSON: %s" % str(e)) return create_json_response(False, 'Invalid Request', 400) if not rdata: return create_json_response(False, 'Invalid Request', 400) pr_list = rdata.get('presigned_payment_requests') if not pr_list: return create_json_response( False, 'Missing presigned_payment_requests data', 400) if not isinstance(pr_list, list): return create_json_response( False, 'presigned_payment_requests data must be a list', 400) # Validate PaymentRequests for pr in pr_list: try: int(pr, 16) except ValueError: return create_json_response( False, 'Payment Request Must Be Hex Encoded', 400) verify_pr = PaymentRequest() try: hex_decoded_pr = pr.decode('hex') if len(hex_decoded_pr) > PAYMENT_REQUEST_SIZE_MAX: log.warn( 'Rejecting Payment Request for Size [ACCEPTED: %d bytes | ACTUAL: %d bytes]' % (PAYMENT_REQUEST_SIZE_MAX, len(hex_decoded_pr))) return create_json_response( False, 'Invalid Payment Request Submitted', 400) verify_pr.ParseFromString(hex_decoded_pr) except Exception as e: log.warn( 'Unable to Parse Submitted Payment Request [ID: %s]: %s' % (id_obj.id, str(e))) return create_json_response( False, 'Invalid Payment Request Submitted', 400) verify_pd = PaymentDetails() try: verify_pd.ParseFromString(verify_pr.serialized_payment_details) except Exception as e: log.warn( 'Unable to Parse Submitted Payment Request [ID: %s]: %s' % (id_obj.id, str(e))) return create_json_response( False, 'Invalid Payment Request Submitted', 400) # Validated! add_count = 0 for pr in pr_list: id_obj.presigned_payment_requests.append(pr) add_count += 1 if add_count == config.presigned_pr_limit: log.info('Presigned Payment Limit Reached [ID: %s]' % id_obj.id) break log.info('Added %d Pre-Signed Payment Requests [ID: %s]' % (add_count, id_obj.id)) resolver.save(id_obj) return create_json_response(data={'payment_requests_added': add_count})