stripe_model_callbacks 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +3 -3
- data/Rakefile +1 -1
- data/app/models/stripe_model_callbacks/application_record.rb +11 -7
- data/app/services/stripe_model_callbacks/account/external_account/updated_service.rb +1 -1
- data/app/services/stripe_model_callbacks/base_service.rb +6 -6
- data/app/services/stripe_model_callbacks/charge/dispute_updated_service.rb +3 -3
- data/app/services/stripe_model_callbacks/charge/updated_service.rb +5 -5
- data/app/services/stripe_model_callbacks/configure_service.rb +54 -27
- data/app/services/stripe_model_callbacks/customer/bank_account/deleted_service.rb +1 -1
- data/app/services/stripe_model_callbacks/customer/discount_updated_service.rb +1 -1
- data/app/services/stripe_model_callbacks/customer/source_updated_service.rb +3 -3
- data/app/services/stripe_model_callbacks/customer/subscription/updated_service.rb +2 -2
- data/app/services/stripe_model_callbacks/customer/updated_service.rb +2 -2
- data/app/services/stripe_model_callbacks/event_mocker_service.rb +14 -8
- data/app/services/stripe_model_callbacks/invoice/updated_service.rb +4 -4
- data/app/services/stripe_model_callbacks/payment_intent/updated_service.rb +19 -0
- data/app/services/stripe_model_callbacks/payment_method/updated_service.rb +19 -0
- data/app/services/stripe_model_callbacks/payout/updated_service.rb +3 -3
- data/app/services/stripe_model_callbacks/plan/updated_service.rb +1 -1
- data/app/services/stripe_model_callbacks/price/updated_service.rb +1 -1
- data/app/services/stripe_model_callbacks/product/updated_service.rb +1 -1
- data/app/services/stripe_model_callbacks/recipient/updated_service.rb +1 -1
- data/app/services/stripe_model_callbacks/review/updated_service.rb +1 -1
- data/app/services/stripe_model_callbacks/setup_intent/updated_service.rb +8 -0
- data/app/services/stripe_model_callbacks/sku/updated_service.rb +1 -1
- data/app/services/stripe_model_callbacks/source/updated_service.rb +4 -4
- data/app/services/stripe_model_callbacks/subscription/state_checker_service.rb +1 -1
- data/app/services/stripe_model_callbacks/subscription_schedule/updated_service.rb +1 -1
- data/app/services/stripe_model_callbacks/sync_everything.rb +17 -2
- data/app/services/stripe_model_callbacks/sync_from_stripe.rb +1 -1
- data/app/services/stripe_model_callbacks/tax_rate/updated_service.rb +3 -3
- data/app/services/stripe_model_callbacks/transfer/updated_service.rb +1 -1
- data/config/rails_best_practices.yml +1 -0
- data/db/migrate/20180206151132_change_activities_trackable_id_to_string.rb +1 -1
- data/db/migrate/20180208091647_change_stripe_subscription_items_quantity_to_integer.rb +1 -1
- data/db/migrate/20181219121712_add_new_primary_id_and_rename_old.rb +2 -2
- data/db/migrate/20230210081405_create_stripe_setup_intents.rb +28 -0
- data/db/migrate/20230331182902_add_amount_captured_to_stripe_charges.rb +6 -0
- data/db/migrate/20230420092307_create_stripe_payment_methods.rb +15 -0
- data/db/migrate/20230421072509_create_stripe_payment_intents.rb +44 -0
- data/db/migrate/20230422074329_add_payment_intent_to_stripe_charges.rb +6 -0
- data/db/migrate/20230422175529_add_payment_intent_to_stripe_refunds.rb +6 -0
- data/db/migrate/20230422180602_change_stripe_refunds_stripe_charge_id_to_nullable.rb +5 -0
- data/db/migrate/20230518072538_change_stripe_setup_intents_payment_method_to_string.rb +7 -0
- data/lib/stripe_model_callbacks/configuration.rb +1 -1
- data/lib/stripe_model_callbacks/event_mocker.rb +1 -1
- data/lib/stripe_model_callbacks/factories/stripe_charges.rb +10 -0
- data/lib/stripe_model_callbacks/factories/stripe_coupons.rb +9 -9
- data/lib/stripe_model_callbacks/factories/stripe_customers.rb +6 -4
- data/lib/stripe_model_callbacks/factories/stripe_payment_intents.rb +17 -0
- data/lib/stripe_model_callbacks/factories/stripe_payment_methods.rb +15 -0
- data/lib/stripe_model_callbacks/factories/stripe_plans.rb +9 -12
- data/lib/stripe_model_callbacks/factories/stripe_products.rb +6 -8
- data/lib/stripe_model_callbacks/factories/stripe_setup_intents.rb +7 -0
- data/lib/stripe_model_callbacks/factories/stripe_subscription_items.rb +6 -7
- data/lib/stripe_model_callbacks/factories/stripe_subscriptions.rb +10 -12
- data/lib/stripe_model_callbacks/factories/stripe_tax_rates.rb +10 -0
- data/lib/stripe_model_callbacks/fixtures/stripe_events/charge/charge.refunded.json +1 -0
- data/lib/stripe_model_callbacks/fixtures/stripe_events/payment_intent/payment_intent.amount_capturable_updated.json +66 -0
- data/lib/stripe_model_callbacks/fixtures/stripe_events/payment_intent/payment_intent.canceled.json +66 -0
- data/lib/stripe_model_callbacks/fixtures/stripe_events/payment_intent/payment_intent.created.json +66 -0
- data/lib/stripe_model_callbacks/fixtures/stripe_events/payment_intent/payment_intent.partially_funded.json +66 -0
- data/lib/stripe_model_callbacks/fixtures/stripe_events/payment_intent/payment_intent.payment_failed.json +66 -0
- data/lib/stripe_model_callbacks/fixtures/stripe_events/payment_intent/payment_intent.processing.json +66 -0
- data/lib/stripe_model_callbacks/fixtures/stripe_events/payment_intent/payment_intent.requires_action.json +66 -0
- data/lib/stripe_model_callbacks/fixtures/stripe_events/payment_intent/payment_intent.succeeded.json +66 -0
- data/lib/stripe_model_callbacks/fixtures/stripe_events/payment_method/payment_method.attached.json +63 -0
- data/lib/stripe_model_callbacks/fixtures/stripe_events/payment_method/payment_method.automatically_updated.json +63 -0
- data/lib/stripe_model_callbacks/fixtures/stripe_events/payment_method/payment_method.card_automatically_updated.json +63 -0
- data/lib/stripe_model_callbacks/fixtures/stripe_events/payment_method/payment_method.detached.json +63 -0
- data/lib/stripe_model_callbacks/fixtures/stripe_events/payment_method/payment_method.updated.json +63 -0
- data/lib/stripe_model_callbacks/fixtures/stripe_events/setup_intent/setup_intent.created.json +47 -0
- data/lib/stripe_model_callbacks/fixtures/stripe_events/setup_intent/setup_intent.updated.json +47 -0
- data/lib/stripe_model_callbacks/models/stripe_charge.rb +47 -3
- data/lib/stripe_model_callbacks/models/stripe_coupon.rb +11 -0
- data/lib/stripe_model_callbacks/models/stripe_customer.rb +12 -0
- data/lib/stripe_model_callbacks/models/stripe_invoice.rb +16 -1
- data/lib/stripe_model_callbacks/models/stripe_payment_intent.rb +126 -0
- data/lib/stripe_model_callbacks/models/stripe_payment_method.rb +32 -0
- data/lib/stripe_model_callbacks/models/stripe_plan.rb +13 -0
- data/lib/stripe_model_callbacks/models/stripe_product.rb +10 -0
- data/lib/stripe_model_callbacks/models/stripe_refund.rb +3 -1
- data/lib/stripe_model_callbacks/models/stripe_setup_intent.rb +21 -0
- data/lib/stripe_model_callbacks/models/stripe_source.rb +2 -1
- data/lib/stripe_model_callbacks/models/stripe_subscription.rb +23 -4
- data/lib/stripe_model_callbacks/models/stripe_subscription_item.rb +10 -1
- data/lib/stripe_model_callbacks/models/stripe_subscription_schedule.rb +1 -1
- data/lib/stripe_model_callbacks/models/stripe_subscription_schedule_phase.rb +1 -1
- data/lib/stripe_model_callbacks/models/stripe_tax_rate.rb +6 -0
- data/lib/stripe_model_callbacks/version.rb +1 -1
- data/lib/stripe_model_callbacks.rb +1 -1
- metadata +45 -13
data/lib/stripe_model_callbacks/fixtures/stripe_events/payment_method/payment_method.detached.json
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
{
|
2
|
+
"id": "evt_1MxwhGIICJxvfdbRjLpH5qNb",
|
3
|
+
"object": "event",
|
4
|
+
"api_version": "2022-11-15",
|
5
|
+
"created": 1681755758,
|
6
|
+
"data": {
|
7
|
+
"object": {
|
8
|
+
"id": "pm_1MxwglIICJxvfdbRkDNKMCwZ",
|
9
|
+
"object": "payment_method",
|
10
|
+
"billing_details": {
|
11
|
+
"address": {
|
12
|
+
"city": null,
|
13
|
+
"country": "DK",
|
14
|
+
"line1": null,
|
15
|
+
"line2": null,
|
16
|
+
"postal_code": null,
|
17
|
+
"state": null
|
18
|
+
},
|
19
|
+
"email": null,
|
20
|
+
"name": null,
|
21
|
+
"phone": null
|
22
|
+
},
|
23
|
+
"card": {
|
24
|
+
"brand": "mastercard",
|
25
|
+
"checks": {
|
26
|
+
"address_line1_check": null,
|
27
|
+
"address_postal_code_check": null,
|
28
|
+
"cvc_check": "pass"
|
29
|
+
},
|
30
|
+
"country": "DK",
|
31
|
+
"exp_month": 6,
|
32
|
+
"exp_year": 2023,
|
33
|
+
"fingerprint": "QJ3sKGzehiISoOQ3",
|
34
|
+
"funding": "debit",
|
35
|
+
"generated_from": null,
|
36
|
+
"last4": "7080",
|
37
|
+
"networks": {
|
38
|
+
"available": [
|
39
|
+
"mastercard"
|
40
|
+
],
|
41
|
+
"preferred": null
|
42
|
+
},
|
43
|
+
"three_d_secure_usage": {
|
44
|
+
"supported": true
|
45
|
+
},
|
46
|
+
"wallet": null
|
47
|
+
},
|
48
|
+
"created": 1681755727,
|
49
|
+
"customer": "cus_NiCY7UI5u0pbJH",
|
50
|
+
"livemode": true,
|
51
|
+
"metadata": {
|
52
|
+
},
|
53
|
+
"type": "card"
|
54
|
+
}
|
55
|
+
},
|
56
|
+
"livemode": true,
|
57
|
+
"pending_webhooks": 1,
|
58
|
+
"request": {
|
59
|
+
"id": null,
|
60
|
+
"idempotency_key": "setatt_1MxwglIICJxvfdbR7jPCO6O3-src_1MxwgmIICJxvfdbRoaqKyWHH"
|
61
|
+
},
|
62
|
+
"type": "payment_method.detached"
|
63
|
+
}
|
data/lib/stripe_model_callbacks/fixtures/stripe_events/payment_method/payment_method.updated.json
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
{
|
2
|
+
"id": "evt_1MxwhGIICJxvfdbRjLpH5qNb",
|
3
|
+
"object": "event",
|
4
|
+
"api_version": "2022-11-15",
|
5
|
+
"created": 1681755758,
|
6
|
+
"data": {
|
7
|
+
"object": {
|
8
|
+
"id": "pm_1MxwglIICJxvfdbRkDNKMCwZ",
|
9
|
+
"object": "payment_method",
|
10
|
+
"billing_details": {
|
11
|
+
"address": {
|
12
|
+
"city": null,
|
13
|
+
"country": "DK",
|
14
|
+
"line1": null,
|
15
|
+
"line2": null,
|
16
|
+
"postal_code": null,
|
17
|
+
"state": null
|
18
|
+
},
|
19
|
+
"email": null,
|
20
|
+
"name": null,
|
21
|
+
"phone": null
|
22
|
+
},
|
23
|
+
"card": {
|
24
|
+
"brand": "mastercard",
|
25
|
+
"checks": {
|
26
|
+
"address_line1_check": null,
|
27
|
+
"address_postal_code_check": null,
|
28
|
+
"cvc_check": "pass"
|
29
|
+
},
|
30
|
+
"country": "DK",
|
31
|
+
"exp_month": 6,
|
32
|
+
"exp_year": 2023,
|
33
|
+
"fingerprint": "QJ3sKGzehiISoOQ3",
|
34
|
+
"funding": "debit",
|
35
|
+
"generated_from": null,
|
36
|
+
"last4": "7080",
|
37
|
+
"networks": {
|
38
|
+
"available": [
|
39
|
+
"mastercard"
|
40
|
+
],
|
41
|
+
"preferred": null
|
42
|
+
},
|
43
|
+
"three_d_secure_usage": {
|
44
|
+
"supported": true
|
45
|
+
},
|
46
|
+
"wallet": null
|
47
|
+
},
|
48
|
+
"created": 1681755727,
|
49
|
+
"customer": "cus_NiCY7UI5u0pbJH",
|
50
|
+
"livemode": true,
|
51
|
+
"metadata": {
|
52
|
+
},
|
53
|
+
"type": "card"
|
54
|
+
}
|
55
|
+
},
|
56
|
+
"livemode": true,
|
57
|
+
"pending_webhooks": 1,
|
58
|
+
"request": {
|
59
|
+
"id": null,
|
60
|
+
"idempotency_key": "setatt_1MxwglIICJxvfdbR7jPCO6O3-src_1MxwgmIICJxvfdbRoaqKyWHH"
|
61
|
+
},
|
62
|
+
"type": "payment_method.updated"
|
63
|
+
}
|
@@ -0,0 +1,47 @@
|
|
1
|
+
{
|
2
|
+
"id": "evt_1MZYBJIICJxvfdbR1IBR1zYM",
|
3
|
+
"object": "event",
|
4
|
+
"api_version": "2022-11-15",
|
5
|
+
"created": 1675941649,
|
6
|
+
"data": {
|
7
|
+
"object": {
|
8
|
+
"id": "seti_1MZYBJIICJxvfdbRFtP2AeIi",
|
9
|
+
"object": "setup_intent",
|
10
|
+
"application": null,
|
11
|
+
"cancellation_reason": null,
|
12
|
+
"client_secret": "seti_1MZYBJIICJxvfdbRFtP2AeIi_secret_NKCapEVr1rCGRLrEjdHGercMNLWCKkH",
|
13
|
+
"created": 1675941649,
|
14
|
+
"customer": "cus_NKCaPfiHnRAtaq",
|
15
|
+
"description": null,
|
16
|
+
"flow_directions": null,
|
17
|
+
"last_setup_error": null,
|
18
|
+
"latest_attempt": null,
|
19
|
+
"livemode": false,
|
20
|
+
"mandate": null,
|
21
|
+
"metadata": {},
|
22
|
+
"next_action": null,
|
23
|
+
"on_behalf_of": null,
|
24
|
+
"payment_method": null,
|
25
|
+
"payment_method_options": {
|
26
|
+
"card": {
|
27
|
+
"mandate_options": null,
|
28
|
+
"network": null,
|
29
|
+
"request_three_d_secure": "automatic"
|
30
|
+
}
|
31
|
+
},
|
32
|
+
"payment_method_types": [
|
33
|
+
"card"
|
34
|
+
],
|
35
|
+
"single_use_mandate": null,
|
36
|
+
"status": "requires_payment_method",
|
37
|
+
"usage": "off_session"
|
38
|
+
}
|
39
|
+
},
|
40
|
+
"livemode": false,
|
41
|
+
"pending_webhooks": 1,
|
42
|
+
"request": {
|
43
|
+
"id": "req_8TabPJe0whYnAR",
|
44
|
+
"idempotency_key": "853d4eff-b952-431c-b204-b0ee45895c1a"
|
45
|
+
},
|
46
|
+
"type": "setup_intent.created"
|
47
|
+
}
|
@@ -0,0 +1,47 @@
|
|
1
|
+
{
|
2
|
+
"id": "evt_1MZYBJIICJxvfdbR1IBR1zYM",
|
3
|
+
"object": "event",
|
4
|
+
"api_version": "2022-11-15",
|
5
|
+
"created": 1675941649,
|
6
|
+
"data": {
|
7
|
+
"object": {
|
8
|
+
"id": "seti_1MZYBJIICJxvfdbRFtP2AeIi",
|
9
|
+
"object": "setup_intent",
|
10
|
+
"application": null,
|
11
|
+
"cancellation_reason": null,
|
12
|
+
"client_secret": "seti_1MZYBJIICJxvfdbRFtP2AeIi_secret_NKCapEVr1rCGRLrEjdHGercMNLWCKkH",
|
13
|
+
"created": 1675941649,
|
14
|
+
"customer": "cus_NKCaPfiHnRAtaq",
|
15
|
+
"description": null,
|
16
|
+
"flow_directions": null,
|
17
|
+
"last_setup_error": null,
|
18
|
+
"latest_attempt": null,
|
19
|
+
"livemode": false,
|
20
|
+
"mandate": null,
|
21
|
+
"metadata": {},
|
22
|
+
"next_action": null,
|
23
|
+
"on_behalf_of": null,
|
24
|
+
"payment_method": null,
|
25
|
+
"payment_method_options": {
|
26
|
+
"card": {
|
27
|
+
"mandate_options": null,
|
28
|
+
"network": null,
|
29
|
+
"request_three_d_secure": "automatic"
|
30
|
+
}
|
31
|
+
},
|
32
|
+
"payment_method_types": [
|
33
|
+
"card"
|
34
|
+
],
|
35
|
+
"single_use_mandate": null,
|
36
|
+
"status": "requires_payment_method",
|
37
|
+
"usage": "off_session"
|
38
|
+
}
|
39
|
+
},
|
40
|
+
"livemode": false,
|
41
|
+
"pending_webhooks": 1,
|
42
|
+
"request": {
|
43
|
+
"id": "req_8TabPJe0whYnAR",
|
44
|
+
"idempotency_key": "853d4eff-b952-431c-b204-b0ee45895c1a"
|
45
|
+
},
|
46
|
+
"type": "setup_intent.updated"
|
47
|
+
}
|
@@ -1,11 +1,20 @@
|
|
1
1
|
class StripeCharge < StripeModelCallbacks::ApplicationRecord
|
2
2
|
belongs_to :stripe_customer, optional: true, primary_key: "stripe_id"
|
3
3
|
belongs_to :stripe_invoice, optional: true, primary_key: "stripe_id"
|
4
|
+
belongs_to :stripe_payment_intent, foreign_key: "payment_intent", optional: true, primary_key: "stripe_id"
|
4
5
|
belongs_to :stripe_source, optional: true, primary_key: "stripe_id"
|
6
|
+
has_many :stripe_invoices, primary_key: "stripe_id"
|
5
7
|
has_many :stripe_orders, primary_key: "stripe_id"
|
6
8
|
has_many :stripe_refunds, primary_key: "stripe_id"
|
7
9
|
has_many :stripe_reviews, primary_key: "stripe_id"
|
8
10
|
|
11
|
+
has_one :latest_charge_on_stripe_payment_intent,
|
12
|
+
class_name: "StripePaymentIntent",
|
13
|
+
foreign_key: "latest_charge",
|
14
|
+
inverse_of: :stripe_latest_charge,
|
15
|
+
primary_key: "stripe_id"
|
16
|
+
|
17
|
+
monetize :amount_captured_cents, allow_nil: true
|
9
18
|
monetize :amount_cents
|
10
19
|
monetize :amount_refunded_cents, allow_nil: true
|
11
20
|
monetize :application_cents, allow_nil: true
|
@@ -22,29 +31,64 @@ class StripeCharge < StripeModelCallbacks::ApplicationRecord
|
|
22
31
|
livemode: object.livemode,
|
23
32
|
stripe_invoice_id: object.invoice,
|
24
33
|
metadata: JSON.generate(object.metadata),
|
25
|
-
|
34
|
+
stripe_id: object.id,
|
35
|
+
stripe_order_id: object.try(:order),
|
26
36
|
stripe_source_id: object.source
|
27
37
|
)
|
28
38
|
|
39
|
+
if object.source.is_a?(String)
|
40
|
+
self.stripe_source_id = object.source
|
41
|
+
elsif object.source
|
42
|
+
self.stripe_source_id = object.source.id
|
43
|
+
end
|
44
|
+
|
29
45
|
assign_amounts_from_stripe(object)
|
30
46
|
|
31
47
|
StripeModelCallbacks::AttributesAssignerService.execute!(
|
32
48
|
model: self,
|
33
49
|
stripe_model: object,
|
34
50
|
attributes: %w[
|
35
|
-
captured currency description dispute outcome refunded fraud_details failure_message failure_code on_behalf_of paid
|
51
|
+
captured currency description dispute outcome refunded fraud_details failure_message failure_code on_behalf_of paid payment_intent
|
36
52
|
receipt_email receipt_number review shipping source_transfer statement_descriptor status transfer_group
|
37
53
|
]
|
38
54
|
)
|
39
55
|
end
|
40
56
|
|
57
|
+
def capture(**)
|
58
|
+
updated_charge = Stripe::Charge.capture(stripe_id, **)
|
59
|
+
assign_from_stripe(updated_charge)
|
60
|
+
save!
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_stripe_mock!
|
64
|
+
mock_charge = Stripe::Charge.create(
|
65
|
+
amount: amount_cents,
|
66
|
+
captured:,
|
67
|
+
currency:,
|
68
|
+
customer: stripe_customer_id,
|
69
|
+
id: stripe_id,
|
70
|
+
paid:,
|
71
|
+
refunded:
|
72
|
+
)
|
73
|
+
assign_from_stripe(mock_charge)
|
74
|
+
save!
|
75
|
+
end
|
76
|
+
|
77
|
+
def refund(**)
|
78
|
+
StripeRefund.create_on_stripe!(charge: stripe_id)
|
79
|
+
updated_charge = Stripe::Charge.retrieve(stripe_id, **)
|
80
|
+
assign_from_stripe(updated_charge)
|
81
|
+
save!
|
82
|
+
end
|
83
|
+
|
41
84
|
private
|
42
85
|
|
43
86
|
def assign_amounts_from_stripe(object)
|
44
87
|
assign_attributes(
|
45
88
|
amount: Money.new(object.amount, object.currency),
|
89
|
+
amount_captured: object.try(:amount_captured) ? Money.new(object.amount_captured, object.currency) : nil,
|
46
90
|
amount_refunded: object.amount_refunded ? Money.new(object.amount_refunded, object.currency) : nil,
|
47
|
-
application: object.application ? Money.new(object.application, object.currency) : nil
|
91
|
+
application: object.try(:application) ? Money.new(object.application, object.currency) : nil
|
48
92
|
)
|
49
93
|
end
|
50
94
|
end
|
@@ -22,4 +22,15 @@ class StripeCoupon < StripeModelCallbacks::ApplicationRecord
|
|
22
22
|
]
|
23
23
|
)
|
24
24
|
end
|
25
|
+
|
26
|
+
def create_stripe_mock!
|
27
|
+
mock_coupon = Stripe::Coupon.create(
|
28
|
+
duration:,
|
29
|
+
duration_in_months:,
|
30
|
+
id: stripe_id,
|
31
|
+
percent_off:
|
32
|
+
)
|
33
|
+
assign_from_stripe(mock_coupon)
|
34
|
+
save!
|
35
|
+
end
|
25
36
|
end
|
@@ -5,6 +5,9 @@ class StripeCustomer < StripeModelCallbacks::ApplicationRecord
|
|
5
5
|
has_many :stripe_invoices, primary_key: "stripe_id"
|
6
6
|
has_many :stripe_invoice_items, primary_key: "stripe_id"
|
7
7
|
has_many :stripe_orders, primary_key: "stripe_id"
|
8
|
+
has_many :stripe_payment_intents, foreign_key: "customer", primary_key: "stripe_id"
|
9
|
+
has_many :stripe_payment_methods, foreign_key: "customer", primary_key: "stripe_id"
|
10
|
+
has_many :stripe_setup_intents, foreign_key: "customer", primary_key: "stripe_id"
|
8
11
|
has_many :stripe_subscriptions, primary_key: "stripe_id"
|
9
12
|
has_many :stripe_subscription_schedules, primary_key: "stripe_id"
|
10
13
|
|
@@ -31,4 +34,13 @@ class StripeCustomer < StripeModelCallbacks::ApplicationRecord
|
|
31
34
|
]
|
32
35
|
)
|
33
36
|
end
|
37
|
+
|
38
|
+
def create_stripe_mock!
|
39
|
+
mock_customer = Stripe::Customer.create(
|
40
|
+
id: stripe_id,
|
41
|
+
source: StripeMock.create_test_helper.generate_card_token
|
42
|
+
)
|
43
|
+
assign_from_stripe(mock_customer)
|
44
|
+
save!
|
45
|
+
end
|
34
46
|
end
|
@@ -4,6 +4,7 @@ class StripeInvoice < StripeModelCallbacks::ApplicationRecord
|
|
4
4
|
belongs_to :stripe_discount, optional: true
|
5
5
|
belongs_to :stripe_subscription, optional: true, primary_key: "stripe_id"
|
6
6
|
|
7
|
+
has_many :stripe_charges, primary_key: "stripe_id"
|
7
8
|
has_many :stripe_invoice_items, autosave: true, primary_key: "stripe_id"
|
8
9
|
|
9
10
|
validates :stripe_id, uniqueness: true
|
@@ -16,11 +17,13 @@ class StripeInvoice < StripeModelCallbacks::ApplicationRecord
|
|
16
17
|
monetize :tax_cents, allow_nil: true
|
17
18
|
monetize :total_cents, allow_nil: true
|
18
19
|
|
20
|
+
has_one_attached :invoice_pdf_file
|
21
|
+
|
19
22
|
def self.stripe_class
|
20
23
|
Stripe::Invoice
|
21
24
|
end
|
22
25
|
|
23
|
-
def assign_from_stripe(object)
|
26
|
+
def assign_from_stripe(object) # rubocop:disable Metrics/AbcSize
|
24
27
|
check_object_is_stripe_class(object)
|
25
28
|
assign_attributes(
|
26
29
|
stripe_charge_id: object.charge,
|
@@ -36,6 +39,7 @@ class StripeInvoice < StripeModelCallbacks::ApplicationRecord
|
|
36
39
|
|
37
40
|
assign_amounts(object)
|
38
41
|
assign_discount_item(object)
|
42
|
+
attach_invoice_pdf(object)
|
39
43
|
assign_tax(object)
|
40
44
|
|
41
45
|
assign_forgiven(object)
|
@@ -114,6 +118,17 @@ private
|
|
114
118
|
end
|
115
119
|
end
|
116
120
|
|
121
|
+
def attach_invoice_pdf(object)
|
122
|
+
if object.respond_to?(:invoice_pdf) && object.invoice_pdf && !invoice_pdf_file.attached?
|
123
|
+
require "open-uri"
|
124
|
+
|
125
|
+
url = URI.parse(object.invoice_pdf)
|
126
|
+
filename = File.basename(url.path)
|
127
|
+
file = url.open
|
128
|
+
invoice_pdf_file.attach(io: file, filename: filename)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
117
132
|
def assign_status_transitions(object)
|
118
133
|
return unless object.respond_to?(:status_transitions)
|
119
134
|
|
@@ -0,0 +1,126 @@
|
|
1
|
+
class StripePaymentIntent < StripeModelCallbacks::ApplicationRecord
|
2
|
+
CANCELLABLE_STATUSES = %w[requires_payment_method requires_capture requires_confirmation requires_action].freeze
|
3
|
+
|
4
|
+
belongs_to :stripe_customer, foreign_key: "customer", optional: true, primary_key: "stripe_id"
|
5
|
+
belongs_to :stripe_latest_charge,
|
6
|
+
class_name: "StripeCharge",
|
7
|
+
foreign_key: "latest_charge",
|
8
|
+
inverse_of: :latest_charge_on_stripe_payment_intent,
|
9
|
+
optional: true,
|
10
|
+
primary_key: "stripe_id"
|
11
|
+
belongs_to :stripe_payment_method, foreign_key: "payment_method", optional: true, primary_key: "stripe_id"
|
12
|
+
|
13
|
+
has_many :stripe_charges, foreign_key: "payment_intent", primary_key: "stripe_id"
|
14
|
+
has_many :stripe_refunds, foreign_key: "payment_intent", primary_key: "stripe_id"
|
15
|
+
|
16
|
+
scope :cancellable, -> { where(status: CANCELLABLE_STATUSES) }
|
17
|
+
|
18
|
+
def self.stripe_class
|
19
|
+
Stripe::PaymentIntent
|
20
|
+
end
|
21
|
+
|
22
|
+
def assign_from_stripe(object)
|
23
|
+
check_object_is_stripe_class(object)
|
24
|
+
|
25
|
+
self.metadata = object.metadata
|
26
|
+
|
27
|
+
StripeModelCallbacks::AttributesAssignerService.execute!(
|
28
|
+
model: self,
|
29
|
+
stripe_model: object,
|
30
|
+
attributes: %w[
|
31
|
+
amount
|
32
|
+
amount_capturable
|
33
|
+
amount_details
|
34
|
+
amount_received
|
35
|
+
application
|
36
|
+
application_fee_amount
|
37
|
+
automatic_payment_methods
|
38
|
+
canceled_at
|
39
|
+
cancellation_reason
|
40
|
+
capture_method
|
41
|
+
client_secret
|
42
|
+
confirmation_method
|
43
|
+
created
|
44
|
+
currency
|
45
|
+
customer
|
46
|
+
description
|
47
|
+
id
|
48
|
+
invoice
|
49
|
+
last_payment_error
|
50
|
+
latest_charge
|
51
|
+
livemode
|
52
|
+
next_action
|
53
|
+
on_behalf_of
|
54
|
+
payment_method
|
55
|
+
payment_method_options
|
56
|
+
payment_method_types
|
57
|
+
processing
|
58
|
+
receipt_email
|
59
|
+
review
|
60
|
+
setup_future_usage
|
61
|
+
shipping
|
62
|
+
statement_descriptor
|
63
|
+
statement_descriptor_suffix
|
64
|
+
status
|
65
|
+
transfer_data
|
66
|
+
transfer_group
|
67
|
+
]
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
def amount_money
|
72
|
+
Money.new(amount, currency)
|
73
|
+
end
|
74
|
+
|
75
|
+
def amount_capturable_money
|
76
|
+
Money.new(amount_capturable, currency)
|
77
|
+
end
|
78
|
+
|
79
|
+
def amount_received_money
|
80
|
+
Money.new(amount_received, currency)
|
81
|
+
end
|
82
|
+
|
83
|
+
def cancel(**args)
|
84
|
+
updated_payment_intent = Stripe::PaymentIntent.cancel(stripe_id, **args)
|
85
|
+
assign_from_stripe(updated_payment_intent)
|
86
|
+
save!
|
87
|
+
end
|
88
|
+
|
89
|
+
def cancellable?
|
90
|
+
CANCELLABLE_STATUSES.include?(status)
|
91
|
+
end
|
92
|
+
|
93
|
+
def capture(**args)
|
94
|
+
updated_payment_intent = Stripe::PaymentIntent.capture(stripe_id, **args)
|
95
|
+
assign_from_stripe(updated_payment_intent)
|
96
|
+
save!
|
97
|
+
end
|
98
|
+
|
99
|
+
def confirm(**args)
|
100
|
+
updated_payment_intent = Stripe::PaymentIntent.confirm(stripe_id, **args)
|
101
|
+
assign_from_stripe(updated_payment_intent)
|
102
|
+
save!
|
103
|
+
end
|
104
|
+
|
105
|
+
def create_stripe_mock!
|
106
|
+
mock_payment_intent = Stripe::PaymentIntent.create(
|
107
|
+
amount:,
|
108
|
+
amount_capturable:,
|
109
|
+
amount_details:,
|
110
|
+
amount_received:,
|
111
|
+
application:,
|
112
|
+
application_fee_amount:,
|
113
|
+
automatic_payment_methods:,
|
114
|
+
canceled_at:,
|
115
|
+
cancellation_reason:,
|
116
|
+
capture_method:,
|
117
|
+
client_secret:,
|
118
|
+
currency:,
|
119
|
+
customer:,
|
120
|
+
id: stripe_id,
|
121
|
+
status:
|
122
|
+
)
|
123
|
+
assign_from_stripe(mock_payment_intent)
|
124
|
+
save!
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class StripePaymentMethod < StripeModelCallbacks::ApplicationRecord
|
2
|
+
belongs_to :stripe_customer, foreign_key: "customer", optional: true, primary_key: "stripe_id"
|
3
|
+
|
4
|
+
has_many :stripe_payment_intents, foreign_key: "payment_method", primary_key: "stripe_id"
|
5
|
+
has_many :stripe_setup_intents, foreign_key: "payment_method", primary_key: "stripe_id"
|
6
|
+
|
7
|
+
def self.stripe_class
|
8
|
+
Stripe::PaymentMethod
|
9
|
+
end
|
10
|
+
|
11
|
+
def assign_from_stripe(object)
|
12
|
+
check_object_is_stripe_class(object)
|
13
|
+
|
14
|
+
self.metadata = object.metadata
|
15
|
+
self.stripe_id = object.id
|
16
|
+
self.stripe_type = object.type
|
17
|
+
|
18
|
+
StripeModelCallbacks::AttributesAssignerService.execute!(
|
19
|
+
model: self,
|
20
|
+
stripe_model: object,
|
21
|
+
attributes: %w[
|
22
|
+
billing_details card created customer livemode
|
23
|
+
]
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_stripe_mock!
|
28
|
+
mock_payment_method = Stripe::PaymentMethod.create(customer:, id: stripe_id, type: "card")
|
29
|
+
assign_from_stripe(mock_payment_method)
|
30
|
+
save!
|
31
|
+
end
|
32
|
+
end
|
@@ -30,6 +30,19 @@ class StripePlan < StripeModelCallbacks::ApplicationRecord
|
|
30
30
|
)
|
31
31
|
end
|
32
32
|
|
33
|
+
def create_stripe_mock!
|
34
|
+
mock_plan = Stripe::Plan.create(
|
35
|
+
id: stripe_id,
|
36
|
+
amount: amount_cents,
|
37
|
+
currency:,
|
38
|
+
interval:,
|
39
|
+
interval_count:,
|
40
|
+
product: stripe_product.stripe_id
|
41
|
+
)
|
42
|
+
assign_from_stripe(mock_plan)
|
43
|
+
save!
|
44
|
+
end
|
45
|
+
|
33
46
|
def name
|
34
47
|
nickname.presence || stripe_product&.name
|
35
48
|
end
|
@@ -34,4 +34,14 @@ class StripeProduct < StripeModelCallbacks::ApplicationRecord
|
|
34
34
|
]
|
35
35
|
)
|
36
36
|
end
|
37
|
+
|
38
|
+
def create_stripe_mock!
|
39
|
+
mock_product = Stripe::Product.create(
|
40
|
+
id: stripe_id,
|
41
|
+
name:,
|
42
|
+
type: "service"
|
43
|
+
)
|
44
|
+
assign_from_stripe(mock_product)
|
45
|
+
save!
|
46
|
+
end
|
37
47
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
class StripeRefund < StripeModelCallbacks::ApplicationRecord
|
2
2
|
belongs_to :stripe_charge, optional: true, primary_key: "stripe_id"
|
3
|
+
belongs_to :stripe_payment_intent, foreign_key: "payment_intent", optional: true, primary_key: "stripe_id"
|
3
4
|
|
4
5
|
monetize :amount_cents, allow_nil: true
|
5
6
|
|
@@ -12,6 +13,7 @@ class StripeRefund < StripeModelCallbacks::ApplicationRecord
|
|
12
13
|
assign_attributes(
|
13
14
|
amount: Money.new(object.amount, object.currency),
|
14
15
|
stripe_charge_id: object.charge,
|
16
|
+
stripe_id: object.id,
|
15
17
|
created: Time.zone.at(object.created),
|
16
18
|
livemode: object.try(:livemode) == true,
|
17
19
|
metadata: JSON.generate(object.metadata)
|
@@ -20,7 +22,7 @@ class StripeRefund < StripeModelCallbacks::ApplicationRecord
|
|
20
22
|
StripeModelCallbacks::AttributesAssignerService.execute!(
|
21
23
|
model: self,
|
22
24
|
stripe_model: object,
|
23
|
-
attributes: %w[balance_transaction currency reason receipt_number status]
|
25
|
+
attributes: %w[balance_transaction currency payment_intent reason receipt_number status]
|
24
26
|
)
|
25
27
|
|
26
28
|
self.failure_reason = object.failure_reason if object.respond_to?(:failure_reason)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class StripeSetupIntent < StripeModelCallbacks::ApplicationRecord
|
2
|
+
belongs_to :stripe_customer, foreign_key: "customer", optional: true, primary_key: "stripe_id"
|
3
|
+
belongs_to :stripe_payment_method, foreign_key: "payment_method", optional: true, primary_key: "stripe_id"
|
4
|
+
|
5
|
+
def self.stripe_class
|
6
|
+
Stripe::SetupIntent
|
7
|
+
end
|
8
|
+
|
9
|
+
def assign_from_stripe(object)
|
10
|
+
check_object_is_stripe_class(object)
|
11
|
+
|
12
|
+
StripeModelCallbacks::AttributesAssignerService.execute!(
|
13
|
+
model: self,
|
14
|
+
stripe_model: object,
|
15
|
+
attributes: %w[
|
16
|
+
application cancellation_reason client_secret created customer description flow_directions last_setup_error latest_attempt livemode mandate metadata
|
17
|
+
next_action on_behalf_of payment_method payment_method_options payment_method_types single_use_mandate status usage
|
18
|
+
]
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
@@ -22,7 +22,8 @@ class StripeSource < StripeModelCallbacks::ApplicationRecord
|
|
22
22
|
assign_ach_credit_transfer(object)
|
23
23
|
|
24
24
|
StripeModelCallbacks::AttributesAssignerService.execute!(
|
25
|
-
model: self,
|
25
|
+
model: self,
|
26
|
+
stripe_model: object,
|
26
27
|
attributes: %w[
|
27
28
|
client_secret created currency flow livemode metadata statement_descriptor
|
28
29
|
status usage
|