mirror of
https://github.com/zulip/zulip.git
synced 2025-11-01 04:23:46 +00:00
integrations/stripe: Fix bug in charge.succeeded.
There are (at least) two types of objects that could be sent with a charge.succeeded event, a Charge (e.g. for credit cards) or a Payment (if they pay by ACH). We were handling the first but not the second. This commit also updates the fixture for the existing charge.succeeded event to the latest API version.
This commit is contained in:
@@ -1,76 +0,0 @@
|
||||
{
|
||||
"created": 1326853478,
|
||||
"livemode": false,
|
||||
"id": "evt_00000000000000",
|
||||
"type": "charge.succeeded",
|
||||
"object": "event",
|
||||
"request": null,
|
||||
"pending_webhooks": 1,
|
||||
"api_version": "2016-07-06",
|
||||
"data": {
|
||||
"object": {
|
||||
"id": "ch_00000000000000",
|
||||
"object": "charge",
|
||||
"amount": 100,
|
||||
"amount_refunded": 0,
|
||||
"application": null,
|
||||
"application_fee": null,
|
||||
"balance_transaction": "txn_00000000000000",
|
||||
"captured": true,
|
||||
"created": 1480671988,
|
||||
"currency": "aud",
|
||||
"customer": null,
|
||||
"description": "My First Test Charge (created for API docs)",
|
||||
"destination": null,
|
||||
"dispute": null,
|
||||
"failure_code": null,
|
||||
"failure_message": null,
|
||||
"fraud_details": {},
|
||||
"invoice": null,
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"order": null,
|
||||
"outcome": null,
|
||||
"paid": true,
|
||||
"receipt_email": null,
|
||||
"receipt_number": null,
|
||||
"refunded": false,
|
||||
"refunds": {
|
||||
"object": "list",
|
||||
"data": [],
|
||||
"has_more": false,
|
||||
"total_count": 0,
|
||||
"url": "/v1/charges/ch_19MDceCV4wXizEw45TBCADlp/refunds"
|
||||
},
|
||||
"review": null,
|
||||
"shipping": null,
|
||||
"source": {
|
||||
"id": "card_00000000000000",
|
||||
"object": "card",
|
||||
"address_city": null,
|
||||
"address_country": null,
|
||||
"address_line1": null,
|
||||
"address_line1_check": null,
|
||||
"address_line2": null,
|
||||
"address_state": null,
|
||||
"address_zip": null,
|
||||
"address_zip_check": null,
|
||||
"brand": "Visa",
|
||||
"country": "US",
|
||||
"customer": null,
|
||||
"cvc_check": null,
|
||||
"dynamic_last4": null,
|
||||
"exp_month": 8,
|
||||
"exp_year": 2017,
|
||||
"funding": "credit",
|
||||
"last4": "4242",
|
||||
"metadata": {},
|
||||
"name": null,
|
||||
"tokenization_method": null
|
||||
},
|
||||
"source_transfer": null,
|
||||
"statement_descriptor": null,
|
||||
"status": "succeeded"
|
||||
}
|
||||
}
|
||||
}
|
||||
89
zerver/webhooks/stripe/fixtures/charge_succeeded__card.json
Normal file
89
zerver/webhooks/stripe/fixtures/charge_succeeded__card.json
Normal file
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"id": "evt_1DbqCuDEQaroqDjsojJSNhmh",
|
||||
"pending_webhooks": 1,
|
||||
"data": {
|
||||
"object": {
|
||||
"id": "ch_000000000000000000000000",
|
||||
"object": "charge",
|
||||
"amount": 100,
|
||||
"amount_refunded": 0,
|
||||
"application": null,
|
||||
"application_fee": null,
|
||||
"balance_transaction": "txn_000000000000000000000000",
|
||||
"captured": true,
|
||||
"created": 1542991183,
|
||||
"currency": "aud",
|
||||
"customer": "cus_00000000000000",
|
||||
"description": null,
|
||||
"destination": null,
|
||||
"dispute": null,
|
||||
"failure_code": null,
|
||||
"failure_message": null,
|
||||
"fraud_details": {
|
||||
},
|
||||
"invoice": "in_000000000000000000000000",
|
||||
"livemode": true,
|
||||
"metadata": {
|
||||
},
|
||||
"on_behalf_of": null,
|
||||
"order": null,
|
||||
"outcome": {
|
||||
"network_status": "approved_by_network",
|
||||
"reason": null,
|
||||
"risk_level": "normal",
|
||||
"seller_message": "Payment complete.",
|
||||
"type": "authorized"
|
||||
},
|
||||
"paid": true,
|
||||
"payment_intent": null,
|
||||
"receipt_email": "user@example.com",
|
||||
"receipt_number": "0000-0000",
|
||||
"refunded": false,
|
||||
"refunds": {
|
||||
"object": "list",
|
||||
"data": [
|
||||
],
|
||||
"has_more": false,
|
||||
"total_count": 0,
|
||||
"url": "/v1/charges/ch_000000000000000000000000/refunds"
|
||||
},
|
||||
"review": null,
|
||||
"shipping": null,
|
||||
"source": {
|
||||
"id": "card_000000000000000000000000",
|
||||
"object": "card",
|
||||
"address_city": "city",
|
||||
"address_country": "country",
|
||||
"address_line1": "line1",
|
||||
"address_line1_check": "unavailable",
|
||||
"address_line2": null,
|
||||
"address_state": "ST",
|
||||
"address_zip": "00000",
|
||||
"address_zip_check": "unavailable",
|
||||
"brand": "Visa",
|
||||
"country": "CO",
|
||||
"customer": "cus_00000000000000",
|
||||
"cvc_check": null,
|
||||
"dynamic_last4": null,
|
||||
"exp_month": 1,
|
||||
"exp_year": 2023,
|
||||
"fingerprint": "0000000000000000",
|
||||
"funding": "credit",
|
||||
"last4": "0000",
|
||||
"metadata": {
|
||||
},
|
||||
"name": "name",
|
||||
"tokenization_method": null
|
||||
},
|
||||
"source_transfer": null,
|
||||
"statement_descriptor": "Zulip Cloud Standard",
|
||||
"status": "succeeded",
|
||||
"transfer_group": null
|
||||
}
|
||||
},
|
||||
"type": "charge.succeeded",
|
||||
"api_version": "2018-11-08",
|
||||
"object": "event",
|
||||
"livemode": true,
|
||||
"created": 1543500572
|
||||
}
|
||||
117
zerver/webhooks/stripe/fixtures/charge_succeeded__invoice.json
Normal file
117
zerver/webhooks/stripe/fixtures/charge_succeeded__invoice.json
Normal file
@@ -0,0 +1,117 @@
|
||||
{
|
||||
"id": "evt_1DbqCuDEQaroqDjsojJSNhmh",
|
||||
"pending_webhooks": 1,
|
||||
"data": {
|
||||
"object": {
|
||||
"failure_message": null,
|
||||
"id": "py_000000000000000000000000",
|
||||
"amount": 100,
|
||||
"refunds": {
|
||||
"total_count": 0,
|
||||
"has_more": false,
|
||||
"url": "\/v1\/charges\/py_000000000000000000000000\/refunds",
|
||||
"object": "list",
|
||||
"data": [
|
||||
|
||||
]
|
||||
},
|
||||
"invoice": "in_000000000000000000000000",
|
||||
"application": null,
|
||||
"source": {
|
||||
"id": "src_000000000000000000000000",
|
||||
"type": "ach_credit_transfer",
|
||||
"usage": "reusable",
|
||||
"amount": null,
|
||||
"flow": "receiver",
|
||||
"customer": "cus_00000000000000",
|
||||
"livemode": true,
|
||||
"object": "source",
|
||||
"owner": {
|
||||
"address": null,
|
||||
"verified_name": null,
|
||||
"email": "username@example.com",
|
||||
"verified_phone": null,
|
||||
"phone": null,
|
||||
"verified_email": null,
|
||||
"verified_address": null,
|
||||
"name": null
|
||||
},
|
||||
"statement_descriptor": null,
|
||||
"metadata": {
|
||||
|
||||
},
|
||||
"client_secret": "secret",
|
||||
"currency": "usd",
|
||||
"receiver": {
|
||||
"amount_received": 100,
|
||||
"refund_attributes_status": "missing",
|
||||
"amount_charged": 100,
|
||||
"amount_returned": 0,
|
||||
"refund_attributes_method": "email",
|
||||
"address": "1234-1234"
|
||||
},
|
||||
"status": "pending",
|
||||
"ach_credit_transfer": {
|
||||
"refund_account_holder_name": null,
|
||||
"bank_name": "WELLS FARGO BANK, N.A.",
|
||||
"fingerprint": "1234",
|
||||
"routing_number": "1234",
|
||||
"swift_code": "WFBIUS6S",
|
||||
"refund_account_holder_type": null,
|
||||
"account_number": "1234",
|
||||
"refund_account_number": null,
|
||||
"refund_routing_number": null
|
||||
},
|
||||
"created": 1543500572
|
||||
},
|
||||
"refunded": false,
|
||||
"statement_descriptor": null,
|
||||
"metadata": {
|
||||
|
||||
},
|
||||
"transfer_group": null,
|
||||
"amount_refunded": 0,
|
||||
"currency": "usd",
|
||||
"application_fee": null,
|
||||
"source_transfer": null,
|
||||
"object": "charge",
|
||||
"receipt_email": "username@example.com",
|
||||
"receipt_number": "1234-1234",
|
||||
"captured": true,
|
||||
"failure_code": null,
|
||||
"description": null,
|
||||
"payment_intent": null,
|
||||
"paid": true,
|
||||
"shipping": null,
|
||||
"livemode": true,
|
||||
"balance_transaction": "txn_000000000000000000000000",
|
||||
"outcome": {
|
||||
"type": "authorized",
|
||||
"network_status": "approved_by_network",
|
||||
"risk_level": "not_assessed",
|
||||
"seller_message": "Payment complete.",
|
||||
"reason": null
|
||||
},
|
||||
"dispute": null,
|
||||
"on_behalf_of": null,
|
||||
"status": "succeeded",
|
||||
"fraud_details": {
|
||||
|
||||
},
|
||||
"order": null,
|
||||
"review": null,
|
||||
"customer": "cus_00000000000000",
|
||||
"destination": null,
|
||||
"created": 1543500571
|
||||
}
|
||||
},
|
||||
"request": {
|
||||
"id": null,
|
||||
"idempotency_key": "in_000000000000000000000000"
|
||||
},
|
||||
"type": "charge.succeeded",
|
||||
"api_version": "2018-11-08",
|
||||
"object": "event",
|
||||
"livemode": true,
|
||||
"created": 1543500572
|
||||
}
|
||||
@@ -27,10 +27,18 @@ class StripeHookTests(WebhookTestCase):
|
||||
self.send_and_test_stream_message('charge_failed', expected_topic, expected_message,
|
||||
content_type="application/x-www-form-urlencoded")
|
||||
|
||||
def test_charge_succeeded(self) -> None:
|
||||
expected_topic = u"charges"
|
||||
expected_message = u"[Charge](https://dashboard.stripe.com/charges/ch_00000000000000) for 1.00 AUD succeeded"
|
||||
self.send_and_test_stream_message('charge_succeeded', expected_topic, expected_message,
|
||||
# Credit card charge
|
||||
def test_charge_succeeded__card(self) -> None:
|
||||
expected_topic = u"cus_00000000000000"
|
||||
expected_message = u"[Charge](https://dashboard.stripe.com/charges/ch_000000000000000000000000) for 1.00 AUD succeeded"
|
||||
self.send_and_test_stream_message('charge_succeeded__card', expected_topic, expected_message,
|
||||
content_type="application/x-www-form-urlencoded")
|
||||
|
||||
# ACH payment (really a 'payment', rather than a 'charge')
|
||||
def test_charge_succeeded__invoice(self) -> None:
|
||||
expected_topic = u"cus_00000000000000"
|
||||
expected_message = u"[Payment](https://dashboard.stripe.com/payments/py_000000000000000000000000) for $1.00 succeeded"
|
||||
self.send_and_test_stream_message('charge_succeeded__invoice', expected_topic, expected_message,
|
||||
content_type="application/x-www-form-urlencoded")
|
||||
|
||||
def test_customer_created(self) -> None:
|
||||
|
||||
@@ -55,7 +55,7 @@ def api_stripe_webhook(request: HttpRequest, user_profile: UserProfile,
|
||||
return json_success()
|
||||
if category == 'charge':
|
||||
if resource == 'charge':
|
||||
if not topic:
|
||||
if not topic: # only in legacy fixtures
|
||||
topic = 'charges'
|
||||
body = "{resource} for {amount} {verbed}".format(
|
||||
resource=linkified_id(object_['id']),
|
||||
@@ -208,6 +208,9 @@ def linkified_id(object_id: str, lower: bool=False) -> str:
|
||||
# I think usage records have URL prefixes like /subscription_items/si_id/usage_record_summaries
|
||||
'mbur': ('Usage record', None),
|
||||
|
||||
# Undocumented :|
|
||||
'py': ('Payment', 'payments'),
|
||||
|
||||
# Connect, Fraud, Orders, etc not implemented
|
||||
} # type: Dict[str, Tuple[str, Optional[str]]]
|
||||
name, url_prefix = names_and_urls[object_id.split('_')[0]]
|
||||
|
||||
Reference in New Issue
Block a user