def get_ym_params(self, amount, pattern, order_id, success_uri, fail_uri, type=PAYMENT_BY_CARD): """Запрос параметров от ym""" request_options = { "pattern_id": pattern, "sum": amount, "customerNumber": order_id, } if type == PaymentCard.PAYMENT_BY_CARD: ym = ExternalPayment(YandexMoneyConfig.INSTANCE_ID) payment = ym.request(request_options) elif type == PaymentCard.PAYMENT_BY_YM: return False else: return False if payment['status'] == "success": request_id = payment['request_id'] else: return False process_options = { "request_id": request_id, 'ext_auth_success_uri': success_uri, 'ext_auth_fail_uri': fail_uri } result = ym.process(process_options) return dict( url=result['acs_uri'], params=result['acs_params'] )
def process_external_payment(instance_id, request_id, auth_success_uri, auth_fail_uri): logger.debug('Processing exteranl payment') external_payment = ExternalPayment(instance_id) process_options = { "request_id": request_id, 'instance_id': instance_id, 'ext_auth_success_uri': auth_success_uri, 'ext_auth_fail_uri': auth_fail_uri } response = external_payment.process(process_options) logger.debug('Response from external_payment.process : {0}'.format(response)) if response['status'] == 'ext_auth_required': acs_uri = response['acs_uri'] acs_params = response['acs_params'] return response['status'], '{0}?{1}'.format(acs_uri, urllib.parse.urlencode(acs_params)) return response['status'], None
def get_ym_params(self, amount, pattern, order_id, success_uri, fail_uri, type=PAYMENT_BY_CARD): """Запрос параметров от ym""" request_options = { "pattern_id": pattern, "sum": amount, "customerNumber": order_id, } if type == PaymentCard.PAYMENT_BY_CARD: ym = ExternalPayment(YandexMoneyConfig.INSTANCE_ID) payment = ym.request(request_options) elif type == PaymentCard.PAYMENT_BY_YM: return False else: return False if payment['status'] == "success": request_id = payment['request_id'] else: return False process_options = { "request_id": request_id, 'ext_auth_success_uri': success_uri, 'ext_auth_fail_uri': fail_uri } result = ym.process(process_options) return dict(url=result['acs_uri'], params=result['acs_params'])
class TestExternalPayment(unittest.TestCase): client_id = '1' @classmethod def request_callback(cls, request): payload = dict(parse_qsl(request.body)) success = payload['client_id'] == cls.client_id resp_body = {'status': 'success' if success else 'refused'} if success: resp_body['instance_id'] = '123' else: resp_body['error'] = 'illegal_param_client_id' return 200, {}, json.dumps(resp_body) def setUp(self): self.api = ExternalPayment(self.client_id) responses.add_callback( responses.POST, re.compile('https?://.*/api/instance-id'), callback=self.request_callback, content_type='application/json', ) @responses.activate def test_invalid_client_id(self): api = ExternalPayment(client_id=self.client_id+'some_data') with self.assertRaises(exceptions.YandexPaymentError) as context: api.instance_id self.assertEqual(exceptions._errors['illegal_param_client_id'].encode('utf-8'), str(context.exception)) self.assertEqual(len(responses.calls), 1) @responses.activate def test_instance_id(self): self.assertEqual(self.api.instance_id, '123') self.assertEqual(len(responses.calls), 1) api2 = ExternalPayment(client_id=self.client_id) self.assertEqual(api2.instance_id, '123') self.assertEqual(len(responses.calls), 1) @responses.activate def test_request(self): def callback(request): payload = dict(parse_qsl(request.body)) success = all(i in payload for i in ['amount', 'to', 'message', 'instance_id']) if success: return 200, {}, json.dumps({'status': 'success', 'request_id': 1, 'contract_amount': payload['amount']}) return 200, {}, json.dumps({'status': 'refused', 'error': 'illegal_params'}) responses.add_callback( responses.POST, re.compile('https?://.*/api/request-external-payment'), callback=callback, content_type='application/json', ) resp = self.api.request({'amount': 100, 'to': 'test', 'message': 'message'}) self.assertEqual(resp.request_id, 1) self.assertEqual(int(resp.contract_amount), 100) with self.assertRaises(exceptions.YandexPaymentError) as context: resp = self.api.request({'message': 'message'}) self.assertEqual(exceptions._errors['illegal_params'].encode('utf-8'), str(context.exception)) self.assertEqual(len(responses.calls), 3) @responses.activate def test_process(self): def callback(request): payload = dict(parse_qsl(request.body)) success = True if payload['request_id'] != 1: success = False success = all(i in payload for i in ['ext_auth_success_uri', 'ext_auth_fail_uri', 'request_token', 'instance_id']) if success: return 200, {}, json.dumps({'status': 'success', 'invoice_id': '0'}) return 200, {}, json.dumps({'status': 'refused', 'error': 'illegal_params'}) responses.add_callback( responses.POST, re.compile('https?://.*/api/process-external-payment'), callback=callback, content_type='application/json', ) resp = self.api.process({'request_id': 1, 'ext_auth_success_uri': 'test', 'ext_auth_fail_uri': 'test_fail', 'request_token': 'request_token', 'instance_id': '123', }) self.assertEqual(resp.status, 'success') self.assertEqual(resp.invoice_id, '0') self.assertEqual(len(responses.calls), 2) def tearDown(self): self.api.zero_cache()
from yandex_money.api import Wallet, ExternalPayment client_id = '6D3FD82502F95CC490D4297F871AB2B934597432FE48B681025011F50C079' response = ExternalPayment.get_instance_id(client_id) if reponse.status == "success": instance_id = response.instance_id; else: # throw exception with reponse->error message # make instance external_payment = ExternalPayment(instance_id); payment_options = { # pattern_id, etc.. } response = external_payment.request(payment_options) if response.status == "success": request_id = response.request_id else: # throw exception with response->message process_options = { "request_id": request_id # other params.. } result = external_payment.process(process_options) # process result according to docs
def check_status(history_id): log = logging.getLogger('payment') history = PaymentHistory.query.get(history_id) if not history: message = 'Check: Not found history, history_id=%s' % history_id log.error(message) return message wallet = PaymentWallet.query.get(history.wallet_id) if not wallet: message = 'Check: Not found wallet, wallet_id=%s' % wallet.id log.error(message) return message card = PaymentCard.get_payment_card(history.wallet_id) if not card: PaymentTask.set_fail(history.report_id, wallet) message = 'Payment: Not found card, for history_id=%s' % history.id log.error(message) return False try: request_options = dict( request_id=history.request_id, ext_auth_success_uri=YandexMoneyConfig.SUCCESS_URI, ext_auth_fail_uri=YandexMoneyConfig.FAIL_URI, ) if card.system == PaymentCard.SYSTEM_MPS: request_options['money_source_token'] = card.token ym = ExternalPayment(YandexMoneyConfig.INSTANCE_ID) result = ym.process(request_options) elif card.system == PaymentCard.SYSTEM_YANDEX: ym = Wallet(card.token) result = ym.process_payment(request_options) else: return False except Exception as e: log.error(e) return False else: if not result or 'status' not in result: PaymentTask.set_fail(history.report_id, wallet) history.delete() message = 'Check: Fail, report_id=%s, request_id=%s' % \ (history.report_id, history.request_id) log.error(message) log.error(result) return message if result['status'] in ('refused', 'ext_auth_required'): PaymentTask.set_fail(history.report_id, wallet) history.delete() message = 'Check: Fail, report_id=%s, request_id=%s' % \ (history.report_id, history.request_id) log.error(message) log.error(result) return message if result['status'] == 'in_progress': history.status = PaymentHistory.STATUS_IN_PROGRESS history.save() elif result['status'] == 'success': if not 'invoice_id' in result: message = 'Check: Fail, not found invoice_id, history_id=%s' % history_id log.error(message) log.error(result) return message history.invoice_id = result['invoice_id'] history.status = PaymentHistory.STATUS_COMPLETE history.save() PaymentTask.set_success(history.report_id, wallet) report = Report.query.get(history.report_id) report.status = Report.STATUS_COMPLETE report.save() return True