Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Document Status

Status
colourBlueGreen
titleDRAFTCLOSED

Document Owner(s)

Capovilla, Evandro

Reviewers

Table of Contents
minLevel1
maxLevel6
outlinefalse
stylenone
typelist
printabletrue

...

  • This solution does not include the “browser height/width” information because paycomet did not implement and does not provide access to send this new field.

  • The address fields provided are not optional and are a new request for Visa payments as a way of detecting fraud.

  • The email will be mandatory and telephone number optional, but both will be sent to paycomet.

  • Only the delivery service mode will show the checkbox to use user data

#1 - Create new fields for the new data needed.

The idea is to create a new input for the user to fill in and we send this information in addition to other relevant information such as the height and width of the browser (Paycomet is working to include height and width in their system, so this solution does not include those properties yet.)

✅ The user will fill in the correct information.

✅ We guarantee that all information provided to Paycomet/Visa belongs to the user.

(error) The user has more fields to fill in.

#2 - Send the email/phone number of user details.

The idea is to use the user's pre-filled information and send it as a request to paycomet.

✅ The user does not need to fill out all the forms.

(error) The user data may not be the same as their Visa credit card information.

✅ Proposed Solution

#1 - Create new fields for the new data needed.

Whitelabel App

Implement new input fields for users to provide additional data necessary for payment processing, specifically: billing address, email, and phone number. This data will be captured, validated, and transmitted to the Payment Service Provider (PSP) Paycomet.

Diagram

...

titlehttps://sequencediagram.org/

...

Fields

Before

New Fields Mandatory

Card Number

Name on Card

Expiry

CVV

Address Line 1

(error)

Address Line 2

(error)

Postal Code

(error)

City

(error)

State

(error)

Country

(error)

Email (user data)

(error)

Cellphone (user data)

(error)

(error) - Optional if email is sent

#1 - Create new fields for the new data needed.

The idea is to create a new input for the user to fill in and we send this information in addition to other relevant information such as the height and width of the browser (Paycomet is working to include height and width in their system, so this solution does not include those properties yet.). It was also agreed that the email and telephone fields will be sent via backend without showing these fields to the user and getting this information in user details.

✅ The user will fill in the correct information.

✅ We guarantee that all information provided to Paycomet/Visa belongs to the user.

(error) The user has more fields to fill in.

#2 - Send the pre-filled data of user details.

The idea is to use the user's pre-filled information and send it as a request to paycomet.

✅ The user does not need to fill out all the forms.

(error) The user data may not be the same as their Visa credit card information.

✅ Proposed Solution

#1 - Create new fields for the new data needed.

Whitelabel App

Implement new input fields for users to provide additional data necessary for payment processing, specifically: billing address, email, and phone number. This data will be captured, validated, and transmitted to the Payment Service Provider (PSP) Paycomet.

Diagram

...

Expand
titlehttps://sequencediagram.org/
Code Block
title Make purchase/No pre-auth

FE->Graphql:CommitOrder
Graphql->Payment-Service:MakePayment
Payment-Service->Paycomet-Service:MakePayment
Paycomet-Service->Paycomet: executePurchase
Paycomet-Service<-Paycomet: result
Payment-Service<-Paycomet-Service:result
Graphql<-Payment-Service:result
FE<-Graphql:result

...

Zenuml sequence macro lite
uuidba86f611-493b-4717-a8f0-4c3cf6d6543d
customContentId5163483248
updatedAt2024-10-24T20:06:51Z

New Forms

...

...

Development

Frontend

Expand
titlepaycomet-credit-card-form/paycomet-credit-card-form.tsx

For postal/zip code we already have a field for this purpose, and it is hidden by the payment variation fields. We can use the same flag to enable or disable these new fields.

Expand
titleCreate useState for each field
Code Block
<TextInputPaycomet
  data-testid="address-city"
  id="addressCity"
  name="addressCity"
  type="hidden"
  value={addressCity}
/>
<TextInputPaycomet
  data-testid="address-country"
  id="addressCountry"
  name="addressCountry"
  type="hidden"
  value={addressCountry}
/>
<TextInputPaycomet
  data-testid="address-line"
  id="addressLine"
  name="addressLine"
  type="hidden"
  value={addressLine}
/>
<TextInputPaycomet
  data-testid="address-state"
  id="addressState"
  name="addressState"
  type="hidden"
  value={addressState}
/>
<TextInputPaycomet
  data-testid="phonenumberphone-number"
  id="phonenumberphoneNumber"
  name="phonenumberphoneNumber"
  type="hidden"
  value={phonenumberphoneNumber}
/>
<TextInputPaycomet
  data-testid="email"
  id="email"
  name="email"
  type="hidden"
  value={email}
/>
Expand
titleSave the input in state ( best option )

You could found other references in IPaymentState/IPaycometState and following the reference below.

Code Block
 <TextInput
  ...
  onChange={handleChange}
  value={paymentValues.billingStreetAddress}
  required
  data-paycomet="billingStreetAddress"
  name="billingStreetAddress" 
/>
Expand
titleIPaycometState - If saving the input in state

If you use the state solution, you must add the user field with phone number and email

Code Block
export interface IPaycometState extends IPaymentState {
  ...,
  user?: {
    phoneNumber: string;
    email: string;
  };
}
Expand
titleUpdate CreatePreAuthorization
Code Block
generateCreatePreAuthorization({
  variables: {
   input: {
    rbiOrderId: rbiOrder.rbiOrderId,
    cardHolderName: paymentValues.nameOnCard,
    ...,
    userPaymentDetails,
    billingAddress
   },
  },
});
Expand
titleorder-payment/use-order-payment.ts
Code Block
commitInput = {
            ...,
            payment: {
              ...,
              billingAddress: {
       ...,         locality: payCometValues.billingCity, //city
 payment: {              country: payCometValues...billingCountry, //country
                billingAddressstreetAddress: {payCometValues.billingStreetAddress, //addressLine
                localitypostalCode: payCometValues.billingCitybillingZip, //citypostalCode
                countryregion: payCometValues.billingCountry, //country
 billingState, //state
              },
              streetAddressuserPaymentDetails: payCometValues.billingStreetAddress, //addressLine{ 
                postalCodephoneNumber: payCometValues.billingZipphoneNumber,
//postalCode                 regionemail: payCometValues.billingStateemail, //state
              },
            },
            ...
          };

Graphql

Expand
titleutils/make-payment.ts

The graphql CommitOrder function has already been made to deal with billingAddress, I put the code here just for reference for name changes.

Code Block
function mapBillingAddress(
  region: string,
  billing: IBillingAddress | undefined,
): PaymentClient.IAddress | undefined {
  if (!billing) {
    return {
      regionCode: region,
    };
  }

  return {
    postalCode: billing.postalCode || undefined, // normalize empty string     //postalCode
    administrativeArea: billing.region,                                        //state
    locality: billing.locality,                                                //city
    regionCode: billing.country ?? region,                                     //country
    streetNumber: billing.streetAddress,                                       //address
  };
}
Expand
titlegraphql/schemas/payments.gql
Code Block
input AdditionalPayment {
  """
  Represents the phone number of the user who owns the requested payment
  """
  phoneNumber: String
  """
  Represents the email of the user who owns the requested payment
  """
  email: String
}

input PaycometPayment {
  ...
  
  """
  Additional Payment Information
  """
  additionalPaymentuserPaymentDetails: AdditionalPaymentUserPaymentDetails
}
Expand
titlegraphql/resolvers/orders.ts
Code Block
paycometSale = {
  ...,
  userDetailsuserPaymentDetails: {
    email: payment?.paycometInput?.additionalPaymentuserPaymentDetails?.email || '',
    phoneNumber: payment?.paycometInput?.additionalPaymentuserPaymentDetails?.phoneNumber || '',
  },
};
export interface IPhoneNumberPaymentDetails { cc: string; phoneNumber: string; }
Expand
titlesrc/functions/graphql/providers/payments.ts
Code Block
payments.ts
Code Block
export interface IUserPaymentDetails {
  email: string;
  phoneNumber: IPhoneNumberPaymentDetailsstring;
}

export interface ICreatePreAuthPaycometRequest {
  userPaymentDetails: IUserPaymentDetails
}

public async createPreAuthorizationPaycomet({
....
}) {
....
const paycometPreauth = await this.paymentsClient.paycometClient.request<ICreatePreAuthorizationResponse>(
        (apis) =>
          apis.paymentsApi.createPreAuthorization({
            iCreatePreAuthorizationRequest: {
              ...,
              billingAddress,
              user: {
                email...,
              billingAddress,
 phonenumber,             user: {
}        },       region: regionCountryemail,
    }),     );   ... }

Intl-Packages

Expand
titlepackages/apis-psp-service/src/payment.dtos.ts
Code Block
export class PaymentBaseRequestDto extendsphonenumber,
PaymentBase {   @IsObject()   @IsOptional()   @ApiProperty({    } required:
false,     type: MerchantDataDto},
    description  region: "PaymentregionCountry,
additional information",   }),
  public merchantData?: MerchantDataDto;
}

export class MerchantDataDto);
  ...
}

Intl-Packages

Expand
titlepackages/apis-psp-service/src/payment.dtos.ts
Code Block
export class PaymentBaseRequestDto extends PaymentBase {
  @IsObject()
  @IsOptional()
  @ApiProperty({
    required: false,
    type: BillingDataDtoUserPaymentDetails,
    description: "User's billingpayment additional information",
  })
  public billinguserPaymentDetails?: BillingDataDtoUserPaymentDetails;
}

export class UserPaymentDetails {
  @IsObject()
  @IsOptional()
  @ApiProperty({
    required: false,
    type: BillingDataDto,
    description: "User's additional information",
  })
  public customer?: CustomerDataDto;
}

export class BillingDataDto {
  //Include the decorators following the pattern
  public billAddrCity;UserPaymentDetails,
    description: "User's mobile phone",
  })
  public billAddrCountrymobilePhone?: string;
  public@IsObject()
billAddrLine1;  @IsOptional()
public billAddrPostCode; @ApiProperty({
 public billAddrState; } required: exportfalse,
class CustomerDataDto {   //Include the decorators following the pattern
  public mobilePhone?: string;type: UserPaymentDetails,
    description: "User's email",
  })
  public email?: string;
}
Expand
titlepackages/packages/payments/src/services/paycomet/generated/api.ts
Code Block
export interface IPhoneNumberPaymentDetails {
  cc: string;
  phoneNumber: string;
}

export interface IUserPaymentDetails {
  email: string;
  phoneNumber: IPhoneNumberPaymentDetailsstring;
}

export interface ICreatePreAuthPaycometRequest {
  userPaymentDetails: IUserPaymentDetails
}

export interface ICreatePreAuthorizationRequest {
    billingAddress: IBillingAddress,
    userPaymentDetails: IUserPaymentDetails
}

...

Expand
titlesrc/paycomet-core/api/api.post-pre-auth.ts
Code Block
languagetypescript
interface IBillingData {
  billAddrCity?: string;
  billAddrCountry?: string;
  billAddrLine1?: string;
  billAddrPostCode?: string;
  billAddrState?: string;
}

interface ICustomerData{
  mobilePhone: IMobilePhone;
  email: string;
}

interface IMobilePhone{
  cc: string;
  subscriber: string;
}

interface IMerchantData {
  billing?: IBillingData;
  customer?: ICustomerData;
}

interface IRequestPaymentBody {
  ...
  customer?merchantData: ICustomerData;
}

interface IRequestPaymentBody {
  ...
  merchantData: IMerchantData;
}

🎛️ Configuration

Info

Include here any configuration required (Sanity, LaunchDarkly flags, etc.) required to enable the solution.

Temporary Feature Flag

payment-fields-variations

🧑‍🚒 QA Plan

[Test Cases] Visa/Sibs - new mandatory fields

⚠️ Call-outs

Note
Tip: Document here any improvement or discussion regarding the feature
IMerchantData;
}

🎛️ Configuration

Info

Include here any configuration required (Sanity, LaunchDarkly flags, etc.) required to enable the solution.

Temporary Feature Flag

payment-fields-variations

🧑‍🚒 QA Plan

[Test Cases] Visa/Sibs - new mandatory fields

⚠️ Call-outs

This functionality is made exclusively for the PSP Paycomet which is used in the Spanish and Portuguese environments.

🖌️ Figma File

...