-
Notifications
You must be signed in to change notification settings - Fork 76
fix: amazon pay fee calculations #11593
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
e4ab35e
fix: amazon pay fee calculations
frosso 75dfc6a
processing fee in order notes and order meta
frosso 8095b4a
wip
frosso 1a57158
Merge branch 'develop' into fix/amazon-pay-fee-calculations
frosso ff8e999
wip
frosso 4ba5971
wip
frosso c0c2be4
wip
frosso 4d0236f
wip
frosso 6efbc37
renaming event to just 'processing fee'
frosso File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| Significance: patch | ||
| Type: fix | ||
|
|
||
| fix: Amazon Pay fee display on order details page and timeline view when the payment was processed with non-card instrument |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,6 +18,10 @@ const FeesBreakdown: React.FC< { | |
| return null; | ||
| } | ||
|
|
||
| if ( event.fee_rates.fee_refunded ) { | ||
| return null; | ||
| } | ||
|
Comment on lines
+21
to
+23
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| const storeCurrency = event.transaction_details.store_currency; | ||
| const feeExchangeRate = event.fee_rates.fee_exchange_rate?.rate || 1; | ||
| const discountFee = event.fee_rates.history | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -55,18 +55,40 @@ public function generate_html_note(): string { | |
| $lines[] = $fx_string; | ||
| } | ||
|
|
||
| $lines[] = $this->compose_fee_string(); | ||
| $fee_rates = $this->captured_event['fee_rates'] ?? []; | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| $fee_refunded = ! empty( $fee_rates['fee_refunded'] ); | ||
|
|
||
| if ( $fee_refunded ) { | ||
| // When the balance transaction has settled, Stripe's processing fee | ||
| // is available as store_fee. Show it and include the net payout. | ||
| // When store_fee is 0 the BT hasn't settled — skip both lines. | ||
| $store_fee = $this->captured_event['transaction_details']['store_fee'] ?? 0; | ||
| $store_currency = $this->captured_event['transaction_details']['store_currency'] ?? ''; | ||
| if ( $store_fee > 0 ) { | ||
| $lines[] = sprintf( | ||
| /* translators: %s is a monetary amount */ | ||
| __( 'Processing fee: -%s', 'woocommerce-payments' ), | ||
| WC_Payments_Utils::format_explicit_currency( | ||
| WC_Payments_Utils::interpret_stripe_amount( (int) $store_fee, $store_currency ), | ||
| $store_currency | ||
| ) | ||
| ); | ||
| $lines[] = $this->compose_net_string(); | ||
| } | ||
| } else { | ||
| $lines[] = $this->compose_fee_string(); | ||
|
|
||
| $fee_breakdown_lines = $this->compose_fee_break_down(); | ||
| if ( null !== $fee_breakdown_lines ) { | ||
| $lines = array_merge( $lines, $fee_breakdown_lines ); | ||
| } | ||
| $fee_breakdown_lines = $this->compose_fee_break_down(); | ||
| if ( null !== $fee_breakdown_lines ) { | ||
| $lines = array_merge( $lines, $fee_breakdown_lines ); | ||
| } | ||
|
|
||
| if ( $this->has_tax() ) { | ||
| $lines[] = $this->compose_tax_string(); | ||
| } | ||
| if ( $this->has_tax() ) { | ||
| $lines[] = $this->compose_tax_string(); | ||
| } | ||
|
|
||
| $lines[] = $this->compose_net_string(); | ||
| $lines[] = $this->compose_net_string(); | ||
| } | ||
|
|
||
| $html = ''; | ||
| foreach ( $lines as $line ) { | ||
|
|
@@ -186,12 +208,15 @@ public function compose_fee_break_down() { | |
| * @return string | ||
| */ | ||
| public function compose_net_string(): string { | ||
| $data = $this->captured_event['transaction_details']; | ||
| $data = $this->captured_event['transaction_details']; | ||
| $fee_rates = $this->captured_event['fee_rates'] ?? []; | ||
| $fee_refunded = ! empty( $fee_rates['fee_refunded'] ); | ||
|
|
||
| // Determine the type of payment and select the appropriate amounts and currencies. | ||
| if ( $this->is_fx_event() ) { | ||
| // For fx events, we need the store amount and currency to display the net amount | ||
| // in the store currency. | ||
| if ( $this->is_fx_event() || $fee_refunded ) { | ||
| // For fx events and refunded-fee events, use store amounts. | ||
| // When the fee was refunded, store_fee holds only Stripe's processing | ||
| // fee while customer_fee was zeroed out, so store values are correct. | ||
| $amount = $data['store_amount']; | ||
| $captured_amount = $data['store_amount_captured']; | ||
| $fee = $data['store_fee']; | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -593,6 +593,20 @@ function ( array $event ) { | |
| return; | ||
| } | ||
|
|
||
| // For refunded Amazon Pay application fees, the captured event's | ||
| // store_fee carries the Stripe processing fee that the merchant | ||
| // actually pays. Use it to backfill the transaction-fee meta so | ||
| // the order page shows the real fee instead of hiding the row. | ||
| $fee_refunded = ! empty( $captured_event['fee_rates']['fee_refunded'] ); | ||
| $store_fee_cents = $captured_event['transaction_details']['store_fee'] ?? 0; | ||
| $store_currency = $captured_event['transaction_details']['store_currency'] ?? $order->get_currency(); | ||
| if ( $fee_refunded && $store_fee_cents > 0 ) { | ||
| $order->update_meta_data( | ||
| self::WCPAY_TRANSACTION_FEE_META_KEY, | ||
| WC_Payments_Utils::interpret_stripe_amount( (int) $store_fee_cents, $store_currency ) | ||
| ); | ||
| } | ||
|
|
||
| $details = ( new WC_Payments_Captured_Event_Note( $captured_event ) )->generate_html_note(); | ||
|
|
||
| // Add fee breakdown details to the note. | ||
|
|
@@ -1409,9 +1423,21 @@ public function attach_transaction_fee_to_order( $order, $charge ) { | |
| // Only set transaction fee if the charge was actually captured. | ||
| // Canceled authorizations should not have fees since no payment was processed. | ||
| if ( $charge && null !== $charge->get_application_fee_amount() && $charge->is_captured() ) { | ||
| // Non-card Amazon Pay transactions have the application fee refunded | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| // server-side; record 0 up front so the order page never displays a | ||
| // pre-refund fee while waiting for the forwarded webhook to arrive. | ||
| $pm_details = $charge->get_payment_method_details() ?? []; | ||
| $pm_type = $pm_details['type'] ?? null; | ||
| $funding = $pm_details['amazon_pay']['funding']['type'] ?? null; | ||
| $is_refunded = 'amazon_pay' === $pm_type && 'card' !== $funding; | ||
|
|
||
| $fee_amount = $is_refunded | ||
| ? 0 | ||
| : WC_Payments_Utils::interpret_stripe_amount( $charge->get_application_fee_amount(), $charge->get_currency() ); | ||
|
|
||
| $order->update_meta_data( | ||
| self::WCPAY_TRANSACTION_FEE_META_KEY, | ||
| WC_Payments_Utils::interpret_stripe_amount( $charge->get_application_fee_amount(), $charge->get_currency() ) | ||
| $fee_amount | ||
| ); | ||
| $order->save_meta_data(); | ||
| } | ||
|
|
@@ -2329,8 +2355,11 @@ private function get_intent_data( WC_Payments_API_Abstract_Intention $intent ): | |
| * @return void | ||
| */ | ||
| private function enqueue_add_fee_breakdown_to_order_notes( WC_Order $order, string $intent_id ) { | ||
| // Delay by 15 seconds to allow the server to process webhooks and | ||
| // adjust fee data (e.g., Amazon Pay non-card fee refunds) before the | ||
| // timeline is fetched for the order note. | ||
| WC_Payments::get_action_scheduler_service()->schedule_job( | ||
| time(), | ||
| time() + 15, | ||
| self::ADD_FEE_BREAKDOWN_TO_ORDER_NOTES, | ||
| [ | ||
| 'order_id' => $order->get_id(), | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.



There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Server sets
fee_rates.fee_refunded: trueon refunded captured events.