Skip to content

Commit

Permalink
[Mobile] Display 'In-Person (POS)' for transactions from mobile POS (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
jaclync authored Dec 3, 2024
1 parent 04f1e4c commit 137745e
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 18 deletions.
4 changes: 4 additions & 0 deletions changelog/mobile-tpv-tracking-channel
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: update

Add support for showing `In-Person (POS)` as the transaction channel for mobile POS transactions in wp-admin Payments, enhancing visibility in both transaction lists and details.
2 changes: 1 addition & 1 deletion client/data/transactions/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export interface Transaction {
transaction_id: string;
date: string;
type: 'charge' | 'refund' | 'financing_payout' | 'financing_paydown';
channel: 'in_person' | 'online';
channel: 'in_person' | 'in_person_pos' | 'online';
// A field to identify the payment's source.
// Usually last 4 digits for card payments, bank name for bank transfers...
source_identifier: string;
Expand Down
3 changes: 2 additions & 1 deletion client/payment-details/summary/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ const composePaymentSummaryItems = ( {
{ isTapToPay( metadata?.reader_model )
? getTapToPayChannel( metadata?.platform )
: getChargeChannel(
charge.payment_method_details?.type
charge.payment_method_details?.type,
metadata
) }
</span>
),
Expand Down
6 changes: 3 additions & 3 deletions client/transactions/list/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ import {
formatExplicitCurrency,
formatExportAmount,
} from 'multi-currency/interface/functions';
import { getChargeChannel } from 'utils/charge';
import { getTransactionChannel } from 'utils/charge';
import Deposit from './deposit';
import ConvertedAmount from './converted-amount';
import autocompleter from 'transactions/autocompleter';
Expand Down Expand Up @@ -473,10 +473,10 @@ export const TransactionsList = (
),
},
channel: {
value: getChargeChannel( txn.channel ),
value: getTransactionChannel( txn.channel ),
display: clickable(
<Fragment>
{ getChargeChannel( txn.channel ) }
{ getTransactionChannel( txn.channel ) }
{ txn.source_device && getSourceDeviceIcon( txn ) }
</Fragment>
),
Expand Down
50 changes: 37 additions & 13 deletions client/utils/charge/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,24 +173,48 @@ export const getChargeAmounts = ( charge: Charge ): ChargeAmounts => {
};

/**
* Displays the transaction's channel: Online | In-Person.
* Displays the transaction's channel: Online | In-Person | In-Person (POS).
* This method is called on the list of transactions page.
*
* This method is called in two places: The individual transaction page, and the list of transactions page.
* In the individual transaction page, we are getting the data from Stripe, so we pass the transaction.type
* which can be card_present or interac_present for In-Person payments.
* In the list of transactions, the type holds the brand of the payment method, so we aren't passing it.
* Instead, we pass the transaction.channel directly, which might be in_person|online.
* Instead, we pass the transaction.channel directly, which might be in_person|in_person_pos|online.
*
* @param {string} type The transaction type.
* @return {string} Online or In-Person.
* @param {string} channel The transaction channel.
* @return {string} Online, In-Person, or In-Person (POS).
*/
export const getTransactionChannel = ( channel: string ): string => {
switch ( channel ) {
case 'in_person':
return __( 'In-Person', 'woocommerce-payments' );
case 'in_person_pos':
return __( 'In-Person (POS)', 'woocommerce-payments' );
default:
return __( 'Online', 'woocommerce-payments' );
}
};

/**
* Displays the channel based on the charge data from Stripe and metadata for a transaction: Online | In-Person | In-Person (POS).
* This method is called in the individual transaction page.
*
* In the individual transaction page, we are getting the data from Stripe, so we pass the charge.type
* which can be card_present or interac_present for In-Person payments. In addition, we pass the transaction metadata
* whose ipp_channel value can be mobile_store_management or mobile_pos that indicates whether the channel is from store
* management or POS in the mobile apps.
*
* @param {string} type The transaction charge type, which can be card_present or interac_present for In-Person payments.
* @param {Record<string, any>} metadata The transaction metadata, which may include ipp_channel indicating the channel source.
* @return {string} Returns 'Online', 'In-Person', or 'In-Person (POS)' based on the transaction type and metadata.
*
*/
export const getChargeChannel = ( type: string ): string => {
if (
type === 'card_present' ||
type === 'interac_present' ||
type === 'in_person'
) {
export const getChargeChannel = (
type: string,
metadata: Record< string, any >
): string => {
if ( type === 'card_present' || type === 'interac_present' ) {
if ( metadata?.ipp_channel === 'mobile_pos' ) {
return __( 'In-Person (POS)', 'woocommerce-payments' );
}
return __( 'In-Person', 'woocommerce-payments' );
}

Expand Down
56 changes: 56 additions & 0 deletions client/utils/charge/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -482,3 +482,59 @@ describe( 'Charge utilities / getChargeAmounts', () => {
} );
} );
} );

jest.mock( '@wordpress/i18n', () => ( {
__: jest.fn( ( text ) => text ),
} ) );

describe( 'Charge utilities / get channel string', () => {
describe( 'getTransactionChannel', () => {
test( 'should return "In-Person (POS)" for in_person_pos channel', () => {
const result = utils.getTransactionChannel( 'in_person_pos' );
expect( result ).toBe( 'In-Person (POS)' );
} );

test( 'should return "In-Person" for in_person channel', () => {
const result = utils.getTransactionChannel( 'in_person' );
expect( result ).toBe( 'In-Person' );
} );

test( 'should return "Online" for online channel', () => {
const result = utils.getTransactionChannel( 'online' );
expect( result ).toBe( 'Online' );
} );

test( 'should return "Online" for null channel', () => {
const result = utils.getTransactionChannel( null );
expect( result ).toBe( 'Online' );
} );
} );

describe( 'getChargeChannel', () => {
test( 'should return "In-Person (POS)" for card_present type with mobile_pos metadata', () => {
const result = utils.getChargeChannel( 'card_present', {
ipp_channel: 'mobile_pos',
} );
expect( result ).toBe( 'In-Person (POS)' );
} );

test( 'should return "In-Person" for card_present type with mobile_store_management metadata', () => {
const result = utils.getChargeChannel( 'card_present', {
ipp_channel: 'mobile_store_management',
} );
expect( result ).toBe( 'In-Person' );
} );

test( 'should return "In-Person" for card_present type with null ipp_channel metadata', () => {
const result = utils.getChargeChannel( 'card_present', {} );
expect( result ).toBe( 'In-Person' );
} );

test( 'should return "Online" for online type', () => {
const result = utils.getChargeChannel( 'online', {
ipp_channel: 'mobile_pos',
} );
expect( result ).toBe( 'Online' );
} );
} );
} );

0 comments on commit 137745e

Please sign in to comment.