pay-rails / pay

Payments for Ruby on Rails apps
https://github.com/pay-rails/pay
MIT License
1.97k stars 316 forks source link

Add Stripe Tax support #354

Closed excid3 closed 2 years ago

excid3 commented 3 years ago

https://stripe.com/docs/tax/subscriptions

We probably want to save the tax details and save it under pay_data on the Billable model. This way, we could apply the tax automatically to every charge and subscription.

user = User.last 

# Enable tax
user.update(automatic_tax: true)

# Calculate tax from IP address
user.update(customer_ip_address: request.ip)

# Calculate tax from Address
user.update(country: "US", postal_code: "90210", state: "CA")

Alternatively, you should be able to control automatic_tax for an individual charge/subscription.

user.subscribe(plan: "growth", automatic_tax: { enabled: true })

For reference, here's Laravel Cashier's implementation: https://github.com/laravel/cashier-stripe/pull/1190 They don't seem to save the tax information in the database.

johnjoubert commented 3 years ago

@excid3 👋 just wanted to bump this issue. I'd really love to see this in an upcoming release as Jumpstart customer 👍

excid3 commented 2 years ago

Currently, we're just storing the We can retrieve all the tax rates from a PaymentIntent's invoice:

pi = Stripe::PaymentIntent.retrieve(id: "pi_3KgVULKXBGcbgpbZ1qf5rgpa", expand: ["invoice.total_tax_amounts.tax_rate"])
=>
#<Stripe::PaymentIntent:0x3aac id=pi_3KgVULKXBGcbgpbZ1qf5rgpa> JSON: {
...
irb(main):009:0> pi
=>
#<Stripe::PaymentIntent:0x3aac id=pi_3KgVULKXBGcbgpbZ1qf5rgpa> JSON: {
  "id": "pi_3KgVULKXBGcbgpbZ1qf5rgpa",
  "object": "payment_intent",
  "amount": 27253,
  "amount_capturable": 0,
  "amount_received": 27253,
  "application": null,
  "application_fee_amount": null,
  "automatic_payment_methods": null,
  "canceled_at": null,
  "cancellation_reason": null,
  "capture_method": "automatic",
  "charges": {"object":"list","data":[{"id":"ch_3KgVULKXBGcbgpbZ1MPIv8hs","object":"charge","amount":27253,"amount_captured":27253,"amount_refunded":0,"application":null,"application_fee":null,"application_fee_amount":null,"balance_transaction":"txn_3KgVULKXBGcbgpbZ1nzzmo2o","billing_details":{"address":{"city":null,"country":null,"line1":null,"line2":null,"postal_code":null,"state":null},"email":null,"name":null,"phone":null},"calculated_statement_descriptor":"PAY RAILS","captured":true,"created":1648046922,"currency":"usd","customer":"cus_LNFszTN0gcJ4RH","description":"Subscription creation","destination":null,"dispute":null,"disputed":false,"failure_code":null,"failure_message":null,"fraud_details":{},"invoice":"in_1KgVULKXBGcbgpbZ7KYliXqj","livemode":false,"metadata":{},"on_behalf_of":null,"order":null,"outcome":{"network_status":"approved_by_network","reason":null,"risk_level":"normal","risk_score":45,"seller_message":"Payment complete.","type":"authorized"},"paid":true,"payment_intent":"pi_3KgVULKXBGcbgpbZ1qf5rgpa","payment_method":"card_1KgVQyKXBGcbgpbZCJjxSssW","payment_method_details":{"card":{"brand":"visa","checks":{"address_line1_check":null,"address_postal_code_check":null,"cvc_check":"pass"},"country":"US","exp_month":4,"exp_year":2024,"fingerprint":"w4XDzQOFakih5EZM","funding":"credit","installments":null,"last4":"4242","mandate":null,"network":"visa","three_d_secure":null,"wallet":null},"type":"card"},"receipt_email":null,"receipt_number":null,"receipt_url":"https://pay.stripe.com/receipts/acct_1E4bfnKXBGcbgpbZ/ch_3KgVULKXBGcbgpbZ1MPIv8hs/rcpt_LNG06insED0gLfXNHHGmM16ejm9oPBQ","refunded":false,"refunds":{"object":"list","data":[],"has_more":false,"total_count":0,"url":"/v1/charges/ch_3KgVULKXBGcbgpbZ1MPIv8hs/refunds"},"review":null,"shipping":null,"source":{"id":"card_1KgVQyKXBGcbgpbZCJjxSssW","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":"cus_LNFszTN0gcJ4RH","cvc_check":"pass","dynamic_last4":null,"exp_month":4,"exp_year":2024,"fingerprint":"w4XDzQOFakih5EZM","funding":"credit","last4":"4242","metadata":{},"name":null,"tokenization_method":null},"source_transfer":null,"statement_descriptor":null,"statement_descriptor_suffix":null,"status":"succeeded","transfer_data":null,"transfer_group":null}],"has_more":false,"total_count":1,"url":"/v1/charges?payment_intent=pi_3KgVULKXBGcbgpbZ1qf5rgpa"},
  "client_secret": "pi_3KgVULKXBGcbgpbZ1qf5rgpa_secret_Ogx1fsQjuJerdwHQNbx7NkB3j",
  "confirmation_method": "automatic",
  "created": 1648046921,
  "currency": "usd",
  "customer": "cus_LNFszTN0gcJ4RH",
  "description": "Subscription creation",
  "invoice": {"id":"in_1KgVULKXBGcbgpbZ7KYliXqj","object":"invoice","account_country":"US","account_name":"Pay","account_tax_ids":null,"amount_due":27253,"amount_paid":27253,"amount_remaining":0,"application_fee_amount":null,"attempt_count":1,"attempted":true,"auto_advance":false,"automatic_tax":{"enabled":true,"status":"complete"},"billing_reason":"subscription_create","charge":"ch_3KgVULKXBGcbgpbZ1MPIv8hs","collection_method":"charge_automatically","created":1648046921,"currency":"usd","custom_fields":null,"customer":"cus_LNFszTN0gcJ4RH","customer_address":{"city":null,"country":"US","line1":null,"line2":null,"postal_code":"70118","state":null},"customer_email":"tax@example.org","customer_name":null,"customer_phone":null,"customer_shipping":null,"customer_tax_exempt":"none","customer_tax_ids":[],"default_payment_method":null,"default_source":null,"default_tax_rates":[],"description":null,"discount":null,"discounts":[],"due_date":null,"ending_balance":0,"footer":null,"hosted_invoice_url":"https://invoice.stripe.com/i/acct_1E4bfnKXBGcbgpbZ/test_YWNjdF8xRTRiZm5LWEJHY2JncGJaLF9MTkcwWEEyZ0QwN0VpeU1QQWZNS21MakNDT1ZiTWpQLDM4NTg4NjEz02004Vezk2PM?s=ap","invoice_pdf":"https://pay.stripe.com/invoice/acct_1E4bfnKXBGcbgpbZ/test_YWNjdF8xRTRiZm5LWEJHY2JncGJaLF9MTkcwWEEyZ0QwN0VpeU1QQWZNS21MakNDT1ZiTWpQLDM4NTg4NjEz02004Vezk2PM/pdf?s=ap","last_finalization_error":null,"lines":{"object":"list","data":[{"id":"il_1KgVULKXBGcbgpbZQq0BTTiH","object":"line_item","amount":24900,"currency":"usd","description":"1 × Sales Tax (Jumpstart Pro) (at $249.00 / year)","discount_amounts":[],"discountable":true,"discounts":[],"livemode":false,"metadata":{},"period":{"end":1679582920,"start":1648046920},"plan":{"id":"price_1Kfs6eKXBGcbgpbZxmESVBT3","object":"plan","active":true,"aggregate_usage":null,"amount":24900,"amount_decimal":"24900","billing_scheme":"per_unit","created":1647895536,"currency":"usd","interval":"year","interval_count":1,"livemode":false,"metadata":{},"nickname":null,"product":"prod_LMbJlZLvn8OfLz","tiers_mode":null,"transform_usage":null,"trial_period_days":null,"usage_type":"licensed"},"price":{"id":"price_1Kfs6eKXBGcbgpbZxmESVBT3","object":"price","active":true,"billing_scheme":"per_unit","created":1647895536,"currency":"usd","livemode":false,"lookup_key":null,"metadata":{},"nickname":null,"product":"prod_LMbJlZLvn8OfLz","recurring":{"aggregate_usage":null,"interval":"year","interval_count":1,"trial_period_days":null,"usage_type":"licensed"},"tax_behavior":"exclusive","tiers_mode":null,"transform_quantity":null,"type":"recurring","unit_amount":24900,"unit_amount_decimal":"24900"},"proration":false,"proration_details":{"credited_items":null},"quantity":1,"subscription":"sub_1KgVUKKXBGcbgpbZXLnAusDS","subscription_item":"si_LNG0U6YSMPlhkx","tax_amounts":[{"amount":2353,"inclusive":false,"tax_rate":"txr_1KOpM7KXBGcbgpbZB0Op4prs"}],"tax_rates":[],"type":"subscription"}],"has_more":false,"total_count":1,"url":"/v1/invoices/in_1KgVULKXBGcbgpbZ7KYliXqj/lines"},"livemode":false,"metadata":{},"next_payment_attempt":null,"number":"2158C7E9-0002","on_behalf_of":null,"paid":true,"paid_out_of_band":false,"payment_intent":"pi_3KgVULKXBGcbgpbZ1qf5rgpa","payment_settings":{"payment_method_options":null,"payment_method_types":null},"period_end":1648046920,"period_start":1648046920,"post_payment_credit_notes_amount":0,"pre_payment_credit_notes_amount":0,"quote":null,"receipt_number":null,"starting_balance":0,"statement_descriptor":null,"status":"paid","status_transitions":{"finalized_at":1648046921,"marked_uncollectible_at":null,"paid_at":1648046920,"voided_at":null},"subscription":"sub_1KgVUKKXBGcbgpbZXLnAusDS","subtotal":24900,"tax":2353,"test_clock":null,"total":27253,"total_discount_amounts":[],"total_tax_amounts":[{"amount":2353,"inclusive":false,"tax_rate":{"id":"txr_1KOpM7KXBGcbgpbZB0Op4prs","object":"tax_rate","active":false,"country":"US","created":1643833387,"description":null,"display_name":"Sales Tax","inclusive":false,"jurisdiction":"Louisiana","livemode":false,"metadata":{},"percentage":9.45,"state":"LA","tax_type":"sales_tax"}}],"transfer_data":null,"webhooks_delivered_at":1648046921},
  "last_payment_error": null,
  "livemode": false,
  "metadata": {},
  "next_action": null,
  "on_behalf_of": null,
  "payment_method": null,
  "payment_method_options": {"card":{"installments":null,"mandate_options":null,"network":null,"request_three_d_secure":"automatic"}},
  "payment_method_types": [
    "card"
  ],
  "processing": null,
  "receipt_email": null,
  "review": null,
  "setup_future_usage": null,
  "shipping": null,
  "source": "card_1KgVQyKXBGcbgpbZCJjxSssW",
  "statement_descriptor": null,
  "statement_descriptor_suffix": null,
  "status": "succeeded",
  "transfer_data": null,
  "transfer_group": null
}
excid3 commented 2 years ago

Added in 4c9bb5d5d72968cd78b1d9243f91a66a627bf11c