Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save peterberkenbosch/261042f3057693d89a57f0d5985223bc to your computer and use it in GitHub Desktop.

Select an option

Save peterberkenbosch/261042f3057693d89a57f0d5985223bc to your computer and use it in GitHub Desktop.
Stripe CreatePaymentIntent: Amount and Fee Handling Explanation

Stripe CreatePaymentIntent: Amount and Fee Handling

Your Observations Are Partially Correct

Amount Parameter (Decimal)

Correct: The amount parameter comes in as a decimal (e.g., 10.00) and gets converted to cents internally:

def base_amount_in_cents
  (@amount.to_d * 100).to_i
end

Fee Amount Parameter (Cents)

Correct: The fee_amount parameter should come in as cents (integer), based on this line:

options[:application_fee_amount] = @fee_amount.to_i if @fee_amount.present?

The .to_i call suggests it's expected to already be an integer in cents.

Does Amount Include the Fee?

This is where it gets nuanced - it depends on the scenario:

Scenario 1: Legacy Customer-Pays-Fees (No Explicit Fee)

When customer_pays_fees: true and fee_amount is not provided:

  • Amount does NOT include fee - it's the base service amount
  • The service calculates and adds the fee using booking_fee percentage
  • Example from spec:
    amount: 10.00                    # Base amount (decimal)
    booking_fee: 0.05                # 5%
    effective_amount: 1050 cents     # 10.00 * 1.05 * 100
    application_fee: 50 cents        # The calculated fee

Scenario 2: Explicit Fee Provided

When fee_amount is explicitly provided:

  • Amount DOES include fee - it's the customer-facing total
  • The fee is passed separately to Stripe
  • No calculation happens - amount is used as-is

Scenario 3: Venue Pays Fees

When customer_pays_fees: false:

  • Amount is exact payment - no fees added
  • Customer pays exactly what's passed in

Summary Table

Parameter Format Example Notes
amount Decimal 10.00 Always decimal, converted to cents internally
fee_amount Cents 50 Already in cents (integer)
Amount semantics Context-dependent - May or may not include fee depending on scenario

Key Takeaway

Yes, there is a format inconsistency:

  • amount parameter is passed as decimal and converted to cents internally
  • fee_amount parameter is passed as cents (integer)

This is a bit awkward but appears to be the current design of the service.

Code References

  • Service: app/services/stripe/create_payment_intent.rb
  • Spec: spec/services/stripe/create_payment_intent_spec.rb
  • Amount conversion: create_payment_intent.rb:39-41
  • Fee handling: create_payment_intent.rb:44-50
  • Stripe API call: create_payment_intent.rb:97
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment