def test_handle_authorized_payment_intent_different_order_channel_slug( _wrapped_update_payment_method, wrapped_update_payment_with_new_transaction, channel_PLN, payment_stripe_for_order, checkout_with_items, stripe_plugin, channel_USD, called, ): # given channel = channel_USD if called else channel_PLN payment = payment_stripe_for_order payment.charge_status = ChargeStatus.PENDING payment.checkout = None payment.save() plugin = stripe_plugin() payment_intent = StripeObject(id="token", last_response={}) payment_intent["amount"] = payment.total payment_intent["currency"] = payment.currency payment_intent["status"] = AUTHORIZED_STATUS payment_intent["payment_method"] = StripeObject() # when handle_authorized_payment_intent(payment_intent, plugin.config, channel.slug) # then assert wrapped_update_payment_with_new_transaction.called == called
def test_handle_successful_payment_intent_for_order_with_pending_payment( _wrapped_update_payment_method, wrapped_checkout_complete, payment_stripe_for_order, stripe_plugin, channel_USD, ): payment = payment_stripe_for_order transaction = payment.transactions.first() transaction.kind = TransactionKind.PENDING transaction.save() plugin = stripe_plugin() payment_intent = StripeObject(id="token", last_response={}) payment_intent["amount_received"] = price_to_minor_unit( payment.total, payment.currency) payment_intent["currency"] = payment.currency payment_intent["setup_future_usage"] = None payment_intent["status"] = SUCCESS_STATUS payment_intent["payment_method"] = StripeObject() handle_successful_payment_intent(payment_intent, plugin.config, channel_USD.slug) payment.refresh_from_db() assert payment.is_active assert payment.charge_status == ChargeStatus.FULLY_CHARGED assert payment.captured_amount == payment.total assert payment.transactions.filter(kind=TransactionKind.CAPTURE).exists() assert wrapped_checkout_complete.called is False
def test_handle_partial_refund(stripe_plugin, payment_stripe_for_order, channel_USD): payment = payment_stripe_for_order payment.captured_amount = payment.total payment.save() payment.transactions.create( is_success=True, action_required=True, kind=TransactionKind.CAPTURE, amount=payment.total, currency=payment.currency, token="ABC", gateway_response={}, ) plugin = stripe_plugin() refund = StripeObject(id="refund_id") refund["amount"] = price_to_minor_unit(Decimal("10"), payment.currency) refund["currency"] = payment.currency refund["last_response"] = None charge = StripeObject() charge["payment_intent"] = "ABC" charge["refunds"] = StripeObject() charge["refunds"]["data"] = [refund] handle_refund(charge, plugin.config, channel_USD.slug) payment.refresh_from_db() assert payment.charge_status == ChargeStatus.PARTIALLY_REFUNDED assert payment.is_active is True assert payment.captured_amount == payment.total - Decimal("10")
def test_get_payment_method_details_missing_charges_data(): payment_intent = StripeObject() payment_intent.charges = {"data": None} payment_method_info = get_payment_method_details(payment_intent) assert payment_method_info is None
def test_get_payment_method_details(): payment_intent = StripeObject() payment_intent.charges = { "data": [{ "payment_method_details": { "type": "card", "card": { "last4": "1234", "exp_year": "2222", "exp_month": "12", "brand": "visa", }, } }] } payment_method_info = get_payment_method_details(payment_intent) assert payment_method_info == PaymentMethodInfo( last_4="1234", exp_year=2222, exp_month=12, brand="visa", type="card", )
def test_handle_successful_payment_intent_different_order_channel_slug( _wrapped_update_payment_method, wrapped_order_captured, payment_stripe_for_order, stripe_plugin, channel_USD, channel_PLN, called, ): # given channel = channel_USD if called else channel_PLN payment = payment_stripe_for_order plugin = stripe_plugin() payment_intent = StripeObject(id="token", last_response={}) payment_intent["amount_received"] = payment.total payment_intent["currency"] = payment.currency payment_intent["capture_method"] = "automatic" payment_intent["setup_future_usage"] = None payment_intent["payment_method"] = StripeObject() # when handle_successful_payment_intent(payment_intent, plugin.config, channel.slug) # then assert wrapped_order_captured.called == called
def _request_and_refresh( self, method_, url_, api_key=None, idempotency_key=None, stripe_version=None, stripe_account=None, headers=None, params=None, ): obj = StripeObject._request( self, method_, url_, api_key, idempotency_key, stripe_version, stripe_account, headers, params, ) self.refresh_from(obj) return self
def test_handle_authorized_payment_intent_for_checkout_inactive_payment( void_mock, inactive_payment_stripe_for_checkout, checkout_with_items, stripe_plugin, channel_USD, ): payment = inactive_payment_stripe_for_checkout payment.transactions.create( is_success=True, action_required=True, kind=TransactionKind.ACTION_TO_CONFIRM, amount=payment.total, currency=payment.currency, token="ABC", gateway_response={}, ) plugin = stripe_plugin() payment_intent = StripeObject(id="ABC", last_response={}) payment_intent["amount"] = price_to_minor_unit(payment.total, payment.currency) payment_intent["currency"] = payment.currency payment_intent["status"] = AUTHORIZED_STATUS handle_authorized_payment_intent(payment_intent, plugin.config, channel_USD.slug) payment.refresh_from_db() assert void_mock.called
def test_handle_authorized_payment_intent_for_checkout( wrapped_checkout_complete, payment_stripe_for_checkout, checkout_with_items, stripe_plugin, channel_USD, ): payment = payment_stripe_for_checkout payment.to_confirm = True payment.save() payment.transactions.create( is_success=True, action_required=True, kind=TransactionKind.ACTION_TO_CONFIRM, amount=payment.total, currency=payment.currency, token="ABC", gateway_response={}, ) plugin = stripe_plugin() payment_intent = StripeObject(id="ABC", last_response={}) payment_intent["amount"] = price_to_minor_unit(payment.total, payment.currency) payment_intent["currency"] = payment.currency payment_intent["status"] = AUTHORIZED_STATUS handle_authorized_payment_intent(payment_intent, plugin.config, channel_USD.slug) payment.refresh_from_db() assert wrapped_checkout_complete.called assert payment.checkout_id is None assert payment.order assert payment.order.checkout_token == str(checkout_with_items.token) transaction = payment.transactions.get(kind=TransactionKind.AUTH) assert transaction.token == payment_intent.id
def get_payment_method_details( payment_intent: StripeObject, ) -> Optional[PaymentMethodInfo]: charges = payment_intent.get("charges", None) payment_method_info = None if charges: charges_data = charges.get("data", []) if not charges_data: return None charge_data = charges_data[-1] payment_method_details = charge_data.get("payment_method_details", {}) if payment_method_details.get("type") == "card": card_details = payment_method_details.get("card", {}) exp_year = card_details.get("exp_year", "") exp_year = int(exp_year) if exp_year else None exp_month = card_details.get("exp_month", "") exp_month = int(exp_month) if exp_month else None payment_method_info = PaymentMethodInfo( last_4=card_details.get("last4", ""), exp_year=exp_year, exp_month=exp_month, brand=card_details.get("brand", ""), type="card", ) return payment_method_info
def test_handle_successful_payment_intent_for_checkout_inactive_payment( refund_mock, wrapped_checkout_complete, inactive_payment_stripe_for_checkout, checkout_with_items, stripe_plugin, channel_USD, ): payment = inactive_payment_stripe_for_checkout payment.to_confirm = True payment.save() payment.transactions.create( is_success=True, action_required=True, kind=TransactionKind.ACTION_TO_CONFIRM, amount=payment.total, currency=payment.currency, token="ABC", gateway_response={}, ) plugin = stripe_plugin() payment_intent = StripeObject(id="ABC", last_response={}) payment_intent["amount_received"] = price_to_minor_unit( payment.total, payment.currency) payment_intent["setup_future_usage"] = None payment_intent["currency"] = payment.currency payment_intent["status"] = SUCCESS_STATUS handle_successful_payment_intent(payment_intent, plugin.config, channel_USD.slug) payment.refresh_from_db() assert refund_mock.called assert not wrapped_checkout_complete.called
def test_handle_failed_payment_intent_different_checkout_channel_slug( wrapped_update_payment_with_new_transaction, wrapped_order_voided, payment_stripe_for_checkout, stripe_plugin, channel_USD, channel_PLN, called, ): # given channel = channel_USD if called else channel_PLN payment = payment_stripe_for_checkout payment.transactions.create( is_success=True, action_required=True, kind=TransactionKind.ACTION_TO_CONFIRM, amount=payment.total, currency=payment.currency, token="ABC", gateway_response={}, ) plugin = stripe_plugin() payment_intent = StripeObject(id="ABC", last_response={}) payment_intent["amount"] = payment.total payment_intent["currency"] = payment.currency payment_intent["status"] = FAILED_STATUSES[0] # when handle_failed_payment_intent(payment_intent, plugin.config, channel.slug) # then assert wrapped_update_payment_with_new_transaction.called == called assert not wrapped_order_voided.called
def test_handle_failed_payment_intent_for_order(stripe_plugin, payment_stripe_for_order, channel_USD): payment = payment_stripe_for_order payment.transactions.create( is_success=True, action_required=True, kind=TransactionKind.ACTION_TO_CONFIRM, amount=payment.total, currency=payment.currency, token="ABC", gateway_response={}, ) plugin = stripe_plugin() payment_intent = StripeObject(id="ABC", last_response={}) payment_intent["amount"] = payment.total payment_intent["currency"] = payment.currency payment_intent["status"] = FAILED_STATUSES[0] handle_failed_payment_intent(payment_intent, plugin.config, channel_USD.slug) payment.refresh_from_db() assert not payment.is_active assert payment.charge_status == ChargeStatus.CANCELLED assert payment.transactions.filter(kind=TransactionKind.CANCEL).exists()
def test_handle_processing_payment_intent_for_checkout_inactive_payment( wrapped_checkout_complete, inactive_payment_stripe_for_checkout, checkout_with_items, stripe_plugin, channel_USD, ): payment = inactive_payment_stripe_for_checkout payment.to_confirm = True payment.save() payment.transactions.create( is_success=True, action_required=True, kind=TransactionKind.ACTION_TO_CONFIRM, amount=payment.total, currency=payment.currency, token="ABC", gateway_response={}, ) plugin = stripe_plugin() payment_intent = StripeObject(id="ABC", last_response={}) payment_intent["amount"] = price_to_minor_unit(payment.total, payment.currency) payment_intent["currency"] = payment.currency payment_intent["status"] = PROCESSING_STATUS handle_processing_payment_intent(payment_intent, plugin.config, channel_USD.slug) assert not wrapped_checkout_complete.called
def test_handle_webhook_events(mocked_webhook_event, webhook_type, fun_to_mock, stripe_plugin, rf): dummy_payload = { "id": "evt_1Ip9ANH1Vac4G4dbE9ch7zGS", } request = rf.post(path="/webhooks/", data=dummy_payload, content_type="application/json") stripe_signature = "1234" request.META["HTTP_STRIPE_SIGNATURE"] = stripe_signature event = Mock() event.type = webhook_type event.data.object = StripeObject() mocked_webhook_event.return_value = event plugin = stripe_plugin() with patch(f"saleor.payment.gateways.stripe.webhooks.{fun_to_mock}" ) as mocked_fun: plugin.webhook(request, "/webhooks/", None) mocked_fun.assert_called_once_with(event.data.object, plugin.config) api_key = plugin.config.connection_params["secret_api_key"] endpoint_secret = plugin.config.connection_params["webhook_secret"] mocked_webhook_event.assert_called_once_with( json.dumps(dummy_payload).encode("utf-8"), stripe_signature, endpoint_secret, api_key=api_key, )
def test_void_payment(mocked_cancel, payment_stripe_for_order, order_with_lines, stripe_plugin): payment = payment_stripe_for_order payment_intent_id = "ABC" payment_intent = StripeObject(id=payment_intent_id) payment_intent["amount"] = price_to_minor_unit(payment.total, payment.currency) payment_intent["status"] = SUCCESS_STATUS payment_intent["currency"] = payment.currency payment_intent["last_response"] = StripeObject() payment_intent["last_response"]["data"] = {"response": "json"} mocked_cancel.return_value = payment_intent payment_info = create_payment_information( payment, payment_token=payment_intent_id, ) gateway_response = GatewayResponse( kind=TransactionKind.AUTH, action_required=False, transaction_id=payment_intent_id, is_success=True, amount=payment_info.amount, currency=payment_info.currency, error="", raw_response={}, ) create_transaction( payment=payment, payment_information=payment_info, kind=TransactionKind.AUTH, gateway_response=gateway_response, ) plugin = stripe_plugin() response = plugin.void_payment(payment_info, None) assert response.is_success is True assert response.action_required is False assert response.kind == TransactionKind.VOID assert response.amount == payment.total assert response.currency == order_with_lines.currency assert response.transaction_id == payment_intent_id
def test_handle_successful_payment_intent_with_metadata( wrapped_update_payment_method, _wrapped_checkout_complete, payment_stripe_for_order, stripe_plugin, channel_USD, metadata, called, ): # given payment = payment_stripe_for_order current_metadata = {"currentkey": "currentvalue"} payment.metadata = metadata payment.charge_status = ChargeStatus.PENDING payment.save() plugin = stripe_plugin() payment_intent = StripeObject(id="token", last_response={}) payment_intent["amount_received"] = price_to_minor_unit( payment.total, payment.currency) payment_intent["metadata"] = current_metadata payment_intent["charges"] = { "data": [{ "payment_method_details": { "type": "card" } }] } payment_intent["amount"] = payment.total payment_intent["currency"] = payment.currency payment_intent["payment_method"] = StripeObject() # when handle_successful_payment_intent(payment_intent, plugin.config, channel_USD.slug) # then if not called: assert wrapped_update_payment_method.call_count == 0 else: wrapped_update_payment_method.assert_called_once_with( plugin.config.connection_params["secret_api_key"], payment_intent.payment_method, metadata, )
def test_working_process_request(self, mock_create): transaction_id = 'stripe_charge_id' mock_create.return_value = StripeObject(id=transaction_id) self._call_process_request() self.assertEqual(PaymentRecord.objects.count(), 1) self.assertEqual(PaymentRecord.objects.all()[0].transaction_id, transaction_id) self.assertEqual(mock_create.call_count, 1)
def test_handle_successful_payment_intent_for_order( _wrapped_update_payment_method, wrapped_checkout_complete, payment_stripe_for_order, stripe_plugin, channel_USD, ): payment = payment_stripe_for_order plugin = stripe_plugin() payment_intent = StripeObject(id="ABC", last_response={}) payment_intent["amount"] = payment.total payment_intent["currency"] = payment.currency payment_intent["capture_method"] = "automatic" payment_intent["payment_method"] = StripeObject() handle_successful_payment_intent(payment_intent, plugin.config, channel_USD.slug) assert wrapped_checkout_complete.called is False
def test_retrieve_payment_intent(mocked_payment_intent): api_key = "api_key" payment_intent_id = "id1234" mocked_payment_intent.retrieve.return_value = StripeObject() intent, _ = retrieve_payment_intent(api_key, payment_intent_id) mocked_payment_intent.retrieve.assert_called_with( payment_intent_id, api_key=api_key, stripe_version=STRIPE_API_VERSION) assert isinstance(intent, StripeObject)
def test_pre_save_plugin_configuration(mocked_stripe, stripe_plugin): webhook_object = StripeObject(id="stripe_webhook_id", last_response={}) webhook_object.secret = "stripe_webhook_secret" mocked_stripe.return_value = webhook_object plugin = stripe_plugin(active=True, webhook_endpoint_id=None, webhook_secret_key=None) configuration = PluginConfiguration.objects.get() plugin.pre_save_plugin_configuration(configuration) webhook_id = get_field_from_plugin_configuration(configuration, "webhook_endpoint_id") webhook_secret = get_field_from_plugin_configuration( configuration, "webhook_secret_key") assert webhook_id["value"] == "stripe_webhook_id" assert webhook_secret["value"] == "stripe_webhook_secret" assert mocked_stripe.called
def test_handle_refund_different_checkout_channel_slug( wrapped_update_payment_with_new_transaction, wrapped_order_refunded, stripe_plugin, payment_stripe_for_checkout, channel_USD, channel_PLN, called, ): # given channel = channel_USD if called else channel_PLN payment = payment_stripe_for_checkout payment.captured_amount = payment.total payment.save() payment.transactions.create( is_success=True, action_required=True, kind=TransactionKind.CAPTURE, amount=payment.total, currency=payment.currency, token="ABC", gateway_response={}, ) plugin = stripe_plugin() refund = StripeObject(id="refund_id") refund["amount"] = price_to_minor_unit(payment.total, payment.currency) refund["currency"] = payment.currency refund["last_response"] = None charge = StripeObject() charge["payment_intent"] = "ABC" charge["refunds"] = StripeObject() charge["refunds"]["data"] = [refund] # when handle_refund(charge, plugin.config, channel.slug) # then assert wrapped_update_payment_with_new_transaction.called == called assert not wrapped_order_refunded.called
def stripe_payment_intent(payment_stripe_for_checkout): payment = payment_stripe_for_checkout payment_intent = StripeObject(id="ABC", last_response={}) payment_intent["amount_received"] = price_to_minor_unit( payment.total, payment.currency) payment_intent["amount"] = price_to_minor_unit(payment.total, payment.currency) payment_intent["setup_future_usage"] = None payment_intent["currency"] = payment.currency payment_intent["status"] = SUCCESS_STATUS return payment_intent
def test_handle_successful_payment_intent_for_checkout( _wrapped_update_payment_method, wrapped_checkout_complete, payment_stripe_for_checkout, checkout_with_items, stripe_plugin, channel_USD, ): payment = payment_stripe_for_checkout payment.to_confirm = True payment.save() payment.transactions.create( is_success=True, action_required=True, kind=TransactionKind.ACTION_TO_CONFIRM, amount=payment.total, currency=payment.currency, token="ABC", gateway_response={}, ) plugin = stripe_plugin() payment_intent = StripeObject(id="ABC", last_response={}) payment_intent["amount_received"] = price_to_minor_unit( payment.total, payment.currency) payment_intent["setup_future_usage"] = None payment_intent["currency"] = payment.currency payment_intent["status"] = SUCCESS_STATUS payment_intent["payment_method"] = StripeObject() handle_successful_payment_intent(payment_intent, plugin.config, channel_USD.slug) payment.refresh_from_db() assert wrapped_checkout_complete.called assert payment.checkout_id is None assert payment.order assert payment.order.checkout_token == str(checkout_with_items.token) transaction = payment.transactions.get(kind=TransactionKind.CAPTURE) assert transaction.token == payment_intent.id
def test_create_payment_intent_with_customer(mocked_payment_intent): customer = StripeObject(id="c_ABC") api_key = "api_key" mocked_payment_intent.create.return_value = StripeObject() intent, error = create_payment_intent(api_key, Decimal(10), "USD", auto_capture=True, customer=customer) mocked_payment_intent.create.assert_called_with( api_key=api_key, amount="1000", currency="USD", capture_method=AUTOMATIC_CAPTURE_METHOD, customer=customer, stripe_version=STRIPE_API_VERSION, ) assert isinstance(intent, StripeObject) assert error is None
def test_handle_successful_payment_intent_different_checkout_channel_slug( _wrapped_update_payment_method, wrapped_process_payment_with_checkout, payment_stripe_for_checkout, checkout_with_items, stripe_plugin, channel_USD, channel_PLN, called, ): # given channel = channel_USD if called else channel_PLN payment = payment_stripe_for_checkout payment.to_confirm = True payment.save() payment.transactions.create( is_success=True, action_required=True, kind=TransactionKind.ACTION_TO_CONFIRM, amount=payment.total, currency=payment.currency, token="ABC", gateway_response={}, ) plugin = stripe_plugin() payment_intent = StripeObject(id="ABC", last_response={}) payment_intent["amount_received"] = price_to_minor_unit( payment.total, payment.currency) payment_intent["setup_future_usage"] = None payment_intent["currency"] = payment.currency payment_intent["status"] = SUCCESS_STATUS payment_intent["payment_method"] = StripeObject() # when handle_successful_payment_intent(payment_intent, plugin.config, channel.slug) # then assert wrapped_process_payment_with_checkout.called == called
def test_pay_autopayable_invoices(self, fake_charge, fake_customer): self._create_autopay_method(fake_customer) fake_charge.return_value = StripeObject(id='transaction_id') original_outbox_length = len(mail.outbox) autopayable_invoice = Invoice.objects.filter( subscription=self.subscription) date_due = autopayable_invoice.first().date_due AutoPayInvoicePaymentHandler().pay_autopayable_invoices(date_due) self.assertAlmostEqual(autopayable_invoice.first().get_total(), 0) self.assertEqual(len(PaymentRecord.objects.all()), 1) self.assertEqual(len(mail.outbox), original_outbox_length + 1)
def test_get_or_create_customer_create(mocked_customer): mocked_customer.create.return_value = StripeObject() api_key = "123" customer_email = "*****@*****.**" customer = get_or_create_customer( api_key=api_key, customer_email=customer_email, customer_id=None, ) assert isinstance(customer, StripeObject) mocked_customer.create.assert_called_with( email=customer_email, api_key=api_key, stripe_version=STRIPE_API_VERSION)
def test_create_payment_intent_manual_auto_capture(mocked_payment_intent): api_key = "api_key" mocked_payment_intent.create.return_value = StripeObject() _intent, _error = create_payment_intent(api_key, Decimal(10), "USD", auto_capture=False) mocked_payment_intent.create.assert_called_with( api_key=api_key, amount="1000", currency="USD", capture_method=MANUAL_CAPTURE_METHOD, stripe_version=STRIPE_API_VERSION, )
def test_list_customer_payment_methods(mocked_payment_method): api_key = "123" customer_id = "c_customer_id" mocked_payment_method.list.return_value = StripeObject() payment_method, error = list_customer_payment_methods( api_key=api_key, customer_id=customer_id) assert error is None assert isinstance(payment_method, StripeObject) mocked_payment_method.list.assert_called_with( api_key=api_key, customer=customer_id, type="card", stripe_version=STRIPE_API_VERSION, )