Document Status | Status |
---|
colour | BlueGreen |
---|
title | DRAFTCLOSED |
---|
|
|
---|
Document Owner(s) | Capovilla, Evandro |
---|
Reviewers | |
---|
Table of Contents |
---|
minLevel | 1 |
---|
maxLevel | 6 |
---|
outline | false |
---|
style | none |
---|
type | list |
---|
printable | true |
---|
|
...
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.
...
billing address.
The “use delivery address” checkbox starts the toggled and the information is pre-filled.
This solution is related to Paycomet.
Fields | Before | New Fields Mandatory |
---|
Card Number | ✅ | ✅ |
Name on Card | ✅ | ✅ |
Expiry | ✅ | ✅ |
CVV | ✅ | ✅ |
Address Line 1 |
| ✅ |
Address Line 2 |
| ✅ |
Postal Code |
| ✅ |
City |
| ✅ |
State |
| ✅ |
Country |
| ✅ |
Email (user data) |
| ✅ |
Cellphone (user data) | | - 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.)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.
...
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.
...
Zenuml sequence macro lite |
---|
uuid | ba86f611-493b-4717-a8f0-4c3cf6d6543d |
---|
customContentId | 5163483248 |
---|
updatedAt | 2024-10-24T20:06:51Z |
---|
|
|
New Forms
...
Development
Frontend
Expand |
---|
title | paycomet-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 |
---|
title | Create 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 |
---|
title | Save 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 |
---|
title | IPaycometState - 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 |
---|
title | Update CreatePreAuthorization |
---|
| Code Block |
---|
generateCreatePreAuthorization({
variables: {
input: {
rbiOrderId: rbiOrder.rbiOrderId,
cardHolderName: paymentValues.nameOnCard,
...,
userPaymentDetails,
billingAddress
},
},
}); |
|
|
Expand |
---|
title | order-payment/use-order-payment.ts |
---|
|
Code Block |
---|
commitInput = {
...,
payment: {
...,
billingAddress: {
locality: payCometValues.billingCity, //city
country: payCometValues.billingCountry, //country
streetAddress: payCometValues.billingStreetAddress, //addressLine
postalCode: payCometValues.billingZip, //postalCode
region: payCometValues.billingState, //state
}, }postalCode: payCometValues.billingZip, //postalCode
... region: }; |
|
Graphql
Expand |
---|
title | utils/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) {payCometValues.billingState, //state
},
returnuserPaymentDetails: {
regionCode: region, }; } return {phoneNumber: payCometValues.phoneNumber,
postalCode: billing.postalCode || undefined, // normalize empty string //postalCodeemail: payCometValues.email,
administrativeArea: billing.region, }
},
...
//state locality: billing.locality, }; |
|
Graphql
Expand |
---|
title | utils/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 //city{
regionCodepostalCode: billing.countrypostalCode ??|| regionundefined, // normalize empty string //postalCode
administrativeArea: billing.region, //country
streetNumber: billing.streetAddress, //state
locality: billing.locality, //address }; } |
|
Expand |
---|
title | graphql/schemas/payments.gql |
---|
|
Code Block |
---|
input AdditionalPayment { """ Represents the phone number of the user who owns the requested payment """ //city
phoneNumber: String """
Represents the email of the user who owns the requested payment
"""
email: String
}
input PaycometPayment {
...regionCode: billing.country ?? region, """ Additional Payment Information//country
""" additionalPayment: AdditionalPayment
} |
|
Expand |
---|
title | graphql/resolvers/orders.ts |
---|
|
Code Block |
---|
paycometSale = {
...,
userDetails: {streetNumber: billing.streetAddress, email: payment?.paycometInput?.additionalPayment?.email || '', phoneNumber: payment?.paycometInput?.additionalPayment?.phoneNumber || '', }, }; |
|
Expand |
---|
title | src/functions/graphql/providers/payments.ts |
---|
|
Code Block |
---|
export interface IPhoneNumberPaymentDetails { cc: string; //address
phoneNumber: string};
} |
|
Expand |
---|
title | graphql/schemas/payments.gql |
---|
|
Code Block |
---|
input AdditionalPayment export{
interface IUserPaymentDetails {"""
email:Represents string;the phone number phoneNumber:of IPhoneNumberPaymentDetails;the }user who exportowns interfacethe ICreatePreAuthPaycometRequestrequested {payment
userPaymentDetails:"""
IUserPaymentDetails } phoneNumber: public async createPreAuthorizationPaycomet({
....
}) {
....
const paycometPreauth = await this.paymentsClient.paycometClient.request<ICreatePreAuthorizationResponse>(
(apis) =>
apis.paymentsApi.createPreAuthorization({
iCreatePreAuthorizationRequest: {
...,
billingAddress,
user: {
email,String
"""
Represents the email of the user who owns the requested payment
"""
email: String
}
input PaycometPayment {
...
"""
Additional Payment Information
"""
userPaymentDetails: UserPaymentDetails
} |
|
Expand |
---|
title | graphql/resolvers/orders.ts |
---|
|
Code Block |
---|
paycometSale = {
...,
userPaymentDetails: {
email: payment?.paycometInput?.userPaymentDetails?.email || '',
phoneNumber: payment?.paycometInput?.userPaymentDetails?.phoneNumber || '',
},
}; |
|
Expand |
---|
title | src/functions/graphql/providers/payments.ts |
---|
|
Code Block |
---|
export interface IUserPaymentDetails {
email: string;
phoneNumber: string;
}
export interface ICreatePreAuthPaycometRequest {
userPaymentDetails: IUserPaymentDetails
}
public async createPreAuthorizationPaycomet({
....
}) {
....
const paycometPreauth = await this.paymentsClient.paycometClient.request<ICreatePreAuthorizationResponse>(
(apis) =>
phonenumber, apis.paymentsApi.createPreAuthorization({
}iCreatePreAuthorizationRequest: {
}, region: regionCountry...,
}), ); ...
} |
|
Intl-Packages
Expand |
---|
title | packages/apis-psp-service/src/payment.dtos.ts |
---|
|
Code Block |
---|
export class PaymentBaseRequestDto extends PaymentBase {
@IsObject()
@IsOptional()
@ApiProperty({ billingAddress,
user: {
required: false, type: MerchantDataDtoemail,
description: "Payment additional information", }) publicphonenumber,
merchantData?: MerchantDataDto; } export class MerchantDataDto { @IsObject() @IsOptional() }
@ApiProperty({ required: false},
typeregion: BillingDataDtoregionCountry,
description: "User's billing information",
})
public billing?: BillingDataDto;
}),
);
...
} |
|
Intl-Packages
Expand |
---|
title | packages/apis-psp-service/src/payment.dtos.ts |
---|
|
Code Block |
---|
export class PaymentBaseRequestDto extends PaymentBase {
@IsObject()
@IsOptional()
@ApiProperty({
required: false,
type: BillingDataDtoUserPaymentDetails,
description: "User's payment additional information",
})
public customeruserPaymentDetails?: CustomerDataDtoUserPaymentDetails;
}
export class BillingDataDto {
//Include the decorators following the pattern
public billAddrCity;UserPaymentDetails {
@IsObject()
@IsOptional()
@ApiProperty({
required: false,
type: UserPaymentDetails,
description: "User's mobile phone",
})
public billAddrCountrymobilePhone?: string;
public billAddrLine1;
@IsObject()
@IsOptional()
public billAddrPostCode;@ApiProperty({
public billAddrState; }required: false,
export class CustomerDataDto { type: UserPaymentDetails,
//Include the decorators following the pattern
description: "User's email",
public mobilePhone?: string; })
public email?: string;
} |
|
Expand |
---|
title | packages/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
} |
|
...
[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
...