pay 3.0.5 → 3.0.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 98d201890dfc59215167a68fe0c2fc23d071ecdc831931eb51c1be85b12d0091
4
- data.tar.gz: 86dbc8f7bebcda970cdbdc9eb22b97ce2716570daeb4a8b64f1d794a350b19fa
3
+ metadata.gz: 645844d5290d8984da36577e87334bf103f4fea1ee209eb90fcf320519508ac7
4
+ data.tar.gz: 9f76933a2538977ff7c14b6b142c26e1a74614e2bc5ef28f105fddcd5e733062
5
5
  SHA512:
6
- metadata.gz: 321eef31d462caade5b3099d3897a7f8e7bf9374e05a76dca1c165329156eb83266c3655f13fb658a1756b91899b4b70e322f131d042c5668431e67529a88214
7
- data.tar.gz: cd2e93563744dec1081687c26e4ad496ed7a9a04e918f95f57c2ff8340e7b15d3b4ef85d948891a6be0a34f09ca69b63787751de2ca42f65a4bafd10449922ec
6
+ metadata.gz: a7bd8e33a5ffee95a6e74135a97bbe0ee12ee811c27d8603e3fde50b35ab3fe3f727d685af71bd07fde72e536417c6d6dfab560953eee02ee11f400c54a50d0c
7
+ data.tar.gz: 6994d66c093c5670e56fc8ae43b3964b707401e00c165f26155180a751c4367566ac35dc6fc1f2ff8f6135e7f9247bf5d62dc7b8be9eaff5b854b47af3702acf
@@ -60,6 +60,18 @@ module Pay
60
60
  payment_processor.refund!(refund_amount)
61
61
  end
62
62
 
63
+ def refunded?
64
+ amount_refunded.to_i > 0
65
+ end
66
+
67
+ def full_refund?
68
+ refunded? && amount == amount_refunded
69
+ end
70
+
71
+ def partial_refund?
72
+ refunded? && !full_refund?
73
+ end
74
+
63
75
  def charged_to
64
76
  case payment_method_type
65
77
  when "card"
@@ -65,7 +65,7 @@ module Pay
65
65
  end
66
66
 
67
67
  def customer_name
68
- [owner.try(:first_name), owner.try(:last_name)].compact.join(" ")
68
+ owner.respond_to?(:name) ? owner.name : [owner.try(:first_name), owner.try(:last_name)].compact.join(" ")
69
69
  end
70
70
 
71
71
  def active?
@@ -24,41 +24,41 @@
24
24
 
25
25
  <div class="bg-white rounded-lg shadow-xl p-4 sm:py-6 sm:px-10 mb-5">
26
26
  <% if @payment.succeeded? %>
27
- <h1 class="text-xl mt-2 mb-4 text-gray-700"><%=t "successful.header" %></h1>
28
- <p class="mb-6"><%=t "successful.description" %></p>
27
+ <h1 class="text-xl mt-2 mb-4 text-gray-700"><%=t "pay.successful.header" %></h1>
28
+ <p class="mb-6"><%=t "pay.successful.description" %></p>
29
29
 
30
30
  <% elsif @payment.canceled? %>
31
- <h1 class="text-xl mt-2 mb-4 text-gray-700"><%=t "cancelled.header" %></h1>
32
- <p class="mb-6"><%=t "cancelled.description" %></p>
31
+ <h1 class="text-xl mt-2 mb-4 text-gray-700"><%=t "pay.cancelled.header" %></h1>
32
+ <p class="mb-6"><%=t "pay.cancelled.description" %></p>
33
33
 
34
34
  <% else %>
35
35
  <div data-payment-intent-target="form" id="payment-elements">
36
36
  <!-- Instructions -->
37
- <h1 class="text-xl mt-2 mb-4 text-gray-700"><%=t "requires_action.header", amount: number_to_currency(@payment.amount / 100.0) %></h1>
38
- <p class="mb-6"><%=t "requires_action.description" %></p>
37
+ <h1 class="text-xl mt-2 mb-4 text-gray-700"><%=t "pay.requires_action.header", amount: number_to_currency(@payment.amount / 100.0) %></h1>
38
+ <p class="mb-6"><%=t "pay.requires_action.description" %></p>
39
39
 
40
40
  <div data-payment-intent-target="cardFields" class="hidden">
41
41
  <!-- Name -->
42
- <label for="cardholder-name" class="inline-block text-sm text-gray-700 font-semibold mb-2"><%=t "requires_action.full_name" %></label>
42
+ <label for="cardholder-name" class="inline-block text-sm text-gray-700 font-semibold mb-2"><%=t "pay.requires_action.full_name" %></label>
43
43
  <input data-payment-intent-target="name" id="cardholder-name" type="text" placeholder="Jane Doe" required autofocus class="mt-1 mb-6 block w-full px-3 py-2 rounded-md border border-gray-300 shadow-sm focus:outline-none focus:border-blue-300 focus:ring focus:ring-blue-200 focus:ring-opacity-50">
44
44
 
45
45
  <!-- Card -->
46
- <label for="card-element" class="inline-block text-sm text-gray-700 font-semibold mb-2"><%=t "requires_action.card" %></label>
46
+ <label for="card-element" class="inline-block text-sm text-gray-700 font-semibold mb-2"><%=t "pay.requires_action.card" %></label>
47
47
  <div data-payment-intent-target="card" id="card-element" class="mt-1 mb-6 block w-full px-3 py-4 rounded-md border border-gray-300 shadow-sm focus:outline-none focus:border-blue-300 focus:ring focus:ring-blue-200 focus:ring-opacity-50"></div>
48
48
  </div>
49
49
 
50
50
  <!-- Pay Button -->
51
51
  <button data-payment-intent-target="button" data-action="click->payment-intent#confirmPayment" class="inline-block w-full px-4 py-3 mb-4 text-white rounded-lg bg-blue-400 hover:bg-blue-500">
52
- <%=t "requires_action.button", amount: number_to_currency(@payment.amount / 100.0) %>
52
+ <%=t "pay.requires_action.button", amount: number_to_currency(@payment.amount / 100.0) %>
53
53
  </button>
54
54
  </div>
55
55
  <% end %>
56
56
 
57
- <%= link_to t("back"), @redirect_to, class: "inline-block w-full px-4 py-3 bg-gray-100 hover:bg-gray-200 text-center text-gray-600 rounded-lg" %>
57
+ <%= link_to t("pay.back"), @redirect_to, class: "inline-block w-full px-4 py-3 bg-gray-100 hover:bg-gray-200 text-center text-gray-600 rounded-lg" %>
58
58
  </div>
59
59
 
60
60
  <p class="text-center text-gray-500 text-sm">
61
- © <%= Date.current.year %> <%= Pay.business_name %> <%=t "all_rights_reserved" %>
61
+ © <%= Date.current.year %> <%= Pay.business_name %> <%=t "pay.all_rights_reserved" %>
62
62
  </p>
63
63
  </div>
64
64
  </div>
@@ -119,14 +119,14 @@
119
119
  if (result.error) {
120
120
  if (result.error.code === 'parameter_invalid_empty' &&
121
121
  result.error.param === 'payment_method_data[billing_details][name]') {
122
- this.errorMessageValue = '<%=t "requires_action.name_missing" %>'
122
+ this.errorMessageValue = '<%=t "pay.requires_action.name_missing" %>'
123
123
  } else {
124
124
  this.errorMessageValue = result.error.message
125
125
  this.statusValue = result.error.payment_intent.status
126
126
  }
127
127
  } else {
128
128
  this.completeValue = true;
129
- this.successMessageValue = '<%=t "requires_action.success" %>'
129
+ this.successMessageValue = '<%=t "pay.requires_action.success" %>'
130
130
  }
131
131
  }
132
132
 
@@ -1,36 +1,44 @@
1
1
  en:
2
- successful:
3
- header: Payment Successful
4
- description: This payment was already successfully confirmed.
5
- cancelled:
6
- header: Payment Cancelled
7
- description: This payment was cancelled.
8
- requires_action:
9
- header: Confirm your %{amount} payment
10
- description: Extra confirmation is needed to process your payment. Please confirm your payment by filling out your payment details below.
11
- full_name: Full name
12
- card: Credit or debit card
13
- button: Pay %{amount}
14
- name_missing: Please provide your name.
15
- success: The payment was successful.
16
- all_rights_reserved: All rights reserved.
17
- back: Go back
18
- receipt:
19
- date: Date
20
- account_billed: Account Billed
21
- product: Product
22
- amount: Amount
23
- charged_to: Charged to
24
- additional_info: Additional Info
25
- errors:
26
- action_required: "This payment attempt failed because additional action is required before it can be completed."
27
- invalid_payment: "This payment attempt failed because of an invalid payment method."
28
- email_required: "Email is required to create a customer"
29
- no_processor: "No payment processor selected. Make sure to set the %{class_name}'s `processor` attribute to either 'stripe' or 'braintree'."
30
- braintree:
31
- authorization: "Either the data you submitted is malformed and does not match the API or the API key you used may not be authorized to perform this action."
32
-
33
2
  pay:
3
+ successful:
4
+ header: Payment Successful
5
+ description: This payment was already successfully confirmed.
6
+ cancelled:
7
+ header: Payment Cancelled
8
+ description: This payment was cancelled.
9
+ requires_action:
10
+ header: Confirm your %{amount} payment
11
+ description: Extra confirmation is needed to process your payment. Please confirm your payment by filling out your payment details below.
12
+ full_name: Full name
13
+ card: Credit or debit card
14
+ button: Pay %{amount}
15
+ name_missing: Please provide your name.
16
+ success: The payment was successful.
17
+ all_rights_reserved: All rights reserved.
18
+ back: Go back
19
+ receipt:
20
+ date: Date
21
+ account_billed: Account Billed
22
+ product: Product
23
+ amount: Amount
24
+ charged_to: Charged to
25
+ additional_info: Additional Info
26
+ refunded: Refunded
27
+ paid: Paid
28
+ invoice:
29
+ amount: "Amount"
30
+ product: "Product"
31
+ quantity: "Quantity"
32
+ subtotal: "Subtotal"
33
+ total: "Total"
34
+ unit_price: "Unit Price"
35
+ errors:
36
+ action_required: "This payment attempt failed because additional action is required before it can be completed."
37
+ invalid_payment: "This payment attempt failed because of an invalid payment method."
38
+ email_required: "Email is required to create a customer"
39
+ no_processor: "No payment processor selected. Make sure to set the %{class_name}'s `processor` attribute to either 'stripe' or 'braintree'."
40
+ braintree:
41
+ authorization: "Either the data you submitted is malformed and does not match the API or the API key you used may not be authorized to perform this action."
34
42
  user_mailer:
35
43
  receipt:
36
44
  subject: "Payment receipt"
@@ -2,7 +2,7 @@ module Pay
2
2
  module Braintree
3
3
  class AuthorizationError < Braintree::Error
4
4
  def message
5
- I18n.t("errors.braintree.authorization")
5
+ I18n.t("pay.errors.braintree.authorization")
6
6
  end
7
7
  end
8
8
  end
data/lib/pay/errors.rb CHANGED
@@ -13,13 +13,13 @@ module Pay
13
13
 
14
14
  class ActionRequired < PaymentError
15
15
  def message
16
- I18n.t("errors.action_required")
16
+ I18n.t("pay.errors.action_required")
17
17
  end
18
18
  end
19
19
 
20
20
  class InvalidPaymentMethod < PaymentError
21
21
  def message
22
- I18n.t("errors.invalid_payment")
22
+ I18n.t("pay.errors.invalid_payment")
23
23
  end
24
24
  end
25
25
  end
data/lib/pay/receipts.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  module Pay
2
2
  module Receipts
3
+ include ActionView::Helpers::NumberHelper
4
+
3
5
  def product
4
6
  Pay.application_name
5
7
  end
@@ -13,17 +15,30 @@ module Pay
13
15
  receipt_pdf.render
14
16
  end
15
17
 
16
- def receipt_pdf
17
- ::Receipts::Receipt.new(
18
+ def receipt_pdf(**options)
19
+ line_items = [
20
+ [I18n.t("pay.receipt.date"), I18n.l(created_at, format: :long)],
21
+ [I18n.t("pay.receipt.account_billed"), "#{customer.customer_name} (#{customer.email})"],
22
+ [I18n.t("pay.receipt.product"), product],
23
+ [I18n.t("pay.receipt.amount"), number_to_currency(amount / 100.0)],
24
+ [I18n.t("pay.receipt.charged_to"), charged_to]
25
+ ]
26
+ line_items << [I18n.t("pay.receipt.additional_info"), customer.owner.extra_billing_info] if customer.owner.extra_billing_info?
27
+ line_items << [I18n.t("pay.receipt.refunded"), number_to_currency(amount_refunded / 100.0)] if refunded?
28
+
29
+ defaults = {
18
30
  id: id,
19
31
  product: product,
20
32
  company: {
21
33
  name: Pay.business_name,
22
34
  address: Pay.business_address,
23
- email: Pay.support_email
35
+ email: Pay.support_email,
36
+ logo: Pay.business_logo
24
37
  },
25
38
  line_items: line_items
26
- )
39
+ }
40
+
41
+ ::Receipts::Receipt.new(defaults.deep_merge(options))
27
42
  end
28
43
 
29
44
  def invoice_filename
@@ -34,35 +49,40 @@ module Pay
34
49
  invoice_pdf.render
35
50
  end
36
51
 
37
- def invoice_pdf
38
- ::Receipts::Invoice.new(
52
+ def invoice_pdf(**options)
53
+ bill_to = [owner.name]
54
+ bill_to += [owner.extra_billing_info] if owner.extra_billing_info?
55
+ bill_to += [nil, owner.email]
56
+
57
+ total = ActionController::Base.helpers.number_to_currency(amount / 100.0)
58
+
59
+ line_items = [
60
+ ["<b>#{I18n.t("pay.invoice.product")}</b>", nil, "<b>#{I18n.t("pay.invoice.amount")}</b>"],
61
+ [product, nil, total],
62
+ [nil, I18n.t("pay.invoice.subtotal"), total],
63
+ [nil, I18n.t("pay.invoice.total"), total]
64
+ ]
65
+
66
+ defaults = {
39
67
  id: id,
40
- issue_date: created_at,
41
- due_date: created_at,
42
- status: "<b><color rgb='#5eba7d'>PAID</color></b>",
43
- bill_to: [
44
- customer.customer_name,
45
- customer.email
46
- ].compact,
68
+ issue_date: I18n.l(created_at, format: :long),
69
+ due_date: I18n.l(created_at, format: :long),
70
+ status: "<b><color rgb='#5eba7d'>#{I18n.t("pay.receipt.paid").upcase}</color></b>",
71
+ bill_to: bill_to,
47
72
  product: product,
48
73
  company: {
49
74
  name: Pay.business_name,
50
75
  address: Pay.business_address,
51
- email: Pay.support_email
76
+ email: Pay.support_email,
77
+ logo: Pay.business_logo
52
78
  },
53
79
  line_items: line_items
54
- )
80
+ }
81
+
82
+ ::Receipts::Invoice.new(defaults.deep_merge(options))
55
83
  end
56
84
 
57
85
  def line_items
58
- line_items = [
59
- [I18n.t("receipt.date"), created_at.to_s],
60
- [I18n.t("receipt.account_billed"), "#{customer.customer_name} (#{customer.email})"],
61
- [I18n.t("receipt.product"), product],
62
- [I18n.t("receipt.amount"), ActionController::Base.helpers.number_to_currency(amount / 100.0)],
63
- [I18n.t("receipt.charged_to"), charged_to]
64
- ]
65
- line_items << [I18n.t("receipt.additional_info"), customer.owner.extra_billing_info] if customer.owner.extra_billing_info?
66
86
  line_items
67
87
  end
68
88
  end
@@ -11,7 +11,7 @@ module Pay
11
11
 
12
12
  # Sync default card
13
13
  if (payment_method_id = pay_customer.customer.invoice_settings.default_payment_method)
14
- Pay::Stripe::PaymentMethod.sync(payment_method_id, {stripe_account: event.try(:account)}.compact)
14
+ Pay::Stripe::PaymentMethod.sync(payment_method_id, stripe_account: event.try(:account))
15
15
 
16
16
  else
17
17
  # No default payment method set
data/lib/pay/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Pay
2
- VERSION = "3.0.5"
2
+ VERSION = "3.0.9"
3
3
  end
data/lib/pay.rb CHANGED
@@ -31,6 +31,7 @@ module Pay
31
31
  mattr_accessor :application_name
32
32
  mattr_accessor :business_address
33
33
  mattr_accessor :business_name
34
+ mattr_accessor :business_logo
34
35
  mattr_accessor :support_email
35
36
 
36
37
  # Email configuration
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pay
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.5
4
+ version: 3.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Charnes
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-09-04 00:00:00.000000000 Z
12
+ date: 2021-09-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails