Skip to content

Commit d3ac9ce

Browse files
AshRelateIQGitHub Enterprise
authored andcommitted
Merge pull request #25 from communities/master
Master -> main (payment protections for buyer user)
2 parents bfd2eac + 6a63168 commit d3ac9ce

File tree

2 files changed

+134
-11
lines changed

2 files changed

+134
-11
lines changed

examples/checkout-sync/flows/Summer_2021_B2B_Checkout.flow

Lines changed: 104 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,23 @@ This may fallback to asynchronous mode even if it's marked synchronous, so
275275
<targetReference>Get_Order_Summary</targetReference>
276276
</connector>
277277
</assignments>
278+
<assignments>
279+
<description>If there&apos;s no payment method on the cart or a purchase order on the order, then the order is in an invalid state and processing should not continue.</description>
280+
<name>Set_Missing_Payment_Error_Message</name>
281+
<label>Set Missing Payment Error Message</label>
282+
<locationX>4758</locationX>
283+
<locationY>1513</locationY>
284+
<assignmentItems>
285+
<assignToReference>errorMessage</assignToReference>
286+
<operator>Assign</operator>
287+
<value>
288+
<stringValue>Cannot complete order. Missing Payment Information.</stringValue>
289+
</value>
290+
</assignmentItems>
291+
<connector>
292+
<targetReference>Session_had_an_Error</targetReference>
293+
</connector>
294+
</assignments>
278295
<assignments>
279296
<description>cartToOrder was designed to be run asynchronously and expects a &quot;Next State&quot;. Without a next state, cartToOrder assumes a failure, so we provide when even though it&apos;s not necessary for the rest of the flow.</description>
280297
<name>Update_Next_State_to_ActivateOrder</name>
@@ -312,8 +329,8 @@ This may fallback to asynchronous mode even if it&apos;s marked synchronous, so
312329
<decisions>
313330
<name>Activate_Order_has_Errors</name>
314331
<label>Activate Order has Errors?</label>
315-
<locationX>5357</locationX>
316-
<locationY>1331</locationY>
332+
<locationX>5356</locationX>
333+
<locationY>1335</locationY>
317334
<defaultConnector>
318335
<targetReference>Get_Final_Checkout_Session</targetReference>
319336
</defaultConnector>
@@ -517,6 +534,35 @@ There&apos;s more smarts that could be here by adding other outcomes of the stat
517534
</connector>
518535
<label>Authorize Payment</label>
519536
</rules>
537+
<rules>
538+
<name>No_Purchase_Order_or_Payment</name>
539+
<conditionLogic>and</conditionLogic>
540+
<conditions>
541+
<leftValueReference>Get_Order_Po_Number.PoNumber</leftValueReference>
542+
<operator>IsNull</operator>
543+
<rightValue>
544+
<booleanValue>true</booleanValue>
545+
</rightValue>
546+
</conditions>
547+
<conditions>
548+
<leftValueReference>webCart.PaymentMethodId</leftValueReference>
549+
<operator>IsNull</operator>
550+
<rightValue>
551+
<booleanValue>true</booleanValue>
552+
</rightValue>
553+
</conditions>
554+
<conditions>
555+
<leftValueReference>webCart.GrandTotalAmount</leftValueReference>
556+
<operator>NotEqualTo</operator>
557+
<rightValue>
558+
<numberValue>0.0</numberValue>
559+
</rightValue>
560+
</conditions>
561+
<connector>
562+
<targetReference>Set_Missing_Payment_Error_Message</targetReference>
563+
</connector>
564+
<label>No Purchase Order or Payment</label>
565+
</rules>
520566
</decisions>
521567
<decisions>
522568
<description>No sense updating a delivery method that hasn&apos;t changed from the default suggestion.</description>
@@ -575,11 +621,11 @@ There&apos;s more smarts that could be here by adding other outcomes of the stat
575621
<recordLookups>
576622
<name>Get_Cart</name>
577623
<label>Get Cart</label>
578-
<locationX>4528</locationX>
579-
<locationY>1103</locationY>
624+
<locationX>4440</locationX>
625+
<locationY>1102</locationY>
580626
<assignNullValuesIfNoRecordsFound>false</assignNullValuesIfNoRecordsFound>
581627
<connector>
582-
<targetReference>Should_Authorize_Payment</targetReference>
628+
<targetReference>Get_Order_Po_Number</targetReference>
583629
</connector>
584630
<filterLogic>and</filterLogic>
585631
<filters>
@@ -593,6 +639,7 @@ There&apos;s more smarts that could be here by adding other outcomes of the stat
593639
<outputReference>webCart</outputReference>
594640
<queriedFields>Id</queriedFields>
595641
<queriedFields>PaymentMethodId</queriedFields>
642+
<queriedFields>GrandTotalAmount</queriedFields>
596643
</recordLookups>
597644
<recordLookups>
598645
<description>Cart Status is used to ensure the cart exists and if the cart is already complete, then forward buyer to the Order Confirmation page.</description>
@@ -751,6 +798,29 @@ There&apos;s more smarts that could be here by adding other outcomes of the stat
751798
<queriedFields>Id</queriedFields>
752799
<queriedFields>OrderId</queriedFields>
753800
</recordLookups>
801+
<recordLookups>
802+
<name>Get_Order_Po_Number</name>
803+
<label>Get Order Po Number</label>
804+
<locationX>4585</locationX>
805+
<locationY>1102</locationY>
806+
<assignNullValuesIfNoRecordsFound>false</assignNullValuesIfNoRecordsFound>
807+
<connector>
808+
<targetReference>Should_Authorize_Payment</targetReference>
809+
</connector>
810+
<filterLogic>and</filterLogic>
811+
<filters>
812+
<field>Id</field>
813+
<operator>EqualTo</operator>
814+
<value>
815+
<elementReference>mainCheckoutSession.OrderId</elementReference>
816+
</value>
817+
</filters>
818+
<getFirstRecordOnly>true</getFirstRecordOnly>
819+
<object>Order</object>
820+
<queriedFields>Id</queriedFields>
821+
<queriedFields>PoNumber</queriedFields>
822+
<storeOutputAutomatically>true</storeOutputAutomatically>
823+
</recordLookups>
754824
<recordLookups>
755825
<description>On the Order Confirmation, we show data from the Order Summary. This gets the order summary id.</description>
756826
<name>Get_Order_Summary</name>
@@ -864,6 +934,7 @@ There&apos;s more smarts that could be here by adding other outcomes of the stat
864934
<outputReference>mainCheckoutSession</outputReference>
865935
<queriedFields>Id</queriedFields>
866936
<queriedFields>IsError</queriedFields>
937+
<queriedFields>OrderId</queriedFields>
867938
</recordLookups>
868939
<recordUpdates>
869940
<description>Copies the contact point address fields into the CartDeliveryGroup. Also, adds the shipping instructions.</description>
@@ -1110,6 +1181,18 @@ There&apos;s more smarts that could be here by adding other outcomes of the stat
11101181
<elementReference>cartId</elementReference>
11111182
</value>
11121183
</inputParameters>
1184+
<inputParameters>
1185+
<name>nextButtonLabel</name>
1186+
<value>
1187+
<stringValue>Next</stringValue>
1188+
</value>
1189+
</inputParameters>
1190+
<inputParameters>
1191+
<name>previousButtonLabel</name>
1192+
<value>
1193+
<stringValue>Previous</stringValue>
1194+
</value>
1195+
</inputParameters>
11131196
<inputsOnNextNavToAssocScrn>UseStoredValues</inputsOnNextNavToAssocScrn>
11141197
<isRequired>true</isRequired>
11151198
<storeOutputAutomatically>true</storeOutputAutomatically>
@@ -1329,15 +1412,21 @@ There&apos;s more smarts that could be here by adding other outcomes of the stat
13291412
<description>This error subflow catches the cases where the built in cartToOrder/activateOrder marked the session as having had an error.</description>
13301413
<name>Session_had_an_Error</name>
13311414
<label>Session had an Error</label>
1332-
<locationX>4807</locationX>
1333-
<locationY>1596</locationY>
1415+
<locationX>4758</locationX>
1416+
<locationY>1752</locationY>
13341417
<flowName>Summer_2021_Subflow_Error</flowName>
13351418
<inputAssignments>
13361419
<name>cartId</name>
13371420
<value>
13381421
<elementReference>cartId</elementReference>
13391422
</value>
13401423
</inputAssignments>
1424+
<inputAssignments>
1425+
<name>ErrorMessage</name>
1426+
<value>
1427+
<elementReference>errorMessage</elementReference>
1428+
</value>
1429+
</inputAssignments>
13411430
<storeOutputAutomatically>true</storeOutputAutomatically>
13421431
</subflows>
13431432
<variables>
@@ -1361,6 +1450,14 @@ There&apos;s more smarts that could be here by adding other outcomes of the stat
13611450
<isInput>false</isInput>
13621451
<isOutput>false</isOutput>
13631452
</variables>
1453+
<variables>
1454+
<description>Used to put error messages in for the error subflow</description>
1455+
<name>errorMessage</name>
1456+
<dataType>String</dataType>
1457+
<isCollection>false</isCollection>
1458+
<isInput>false</isInput>
1459+
<isOutput>false</isOutput>
1460+
</variables>
13641461
<variables>
13651462
<name>mainCheckoutSession</name>
13661463
<dataType>SObject</dataType>

examples/lwc/force-app/main/default/lwc/paymentMethod/paymentMethod.js

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -315,12 +315,16 @@ export default class PaymentMethod extends LightningElement {
315315
* then makes an apex call which in turns makes a call to Payment.tokenize endpoint
316316
*/
317317
handlePaymentButton() {
318-
//Get the address selected
319-
const selectedAddress = this._addresses.filter(add => add.id === this.selectedBillingAddress)[0];
318+
const selectedAddressResult = this.getBillingAddress();
320319

321320
if (
322321
this.selectedPaymentType !== Constants.PaymentTypeEnum.CARDPAYMENT
323322
) {
323+
if (selectedAddressResult.error) {
324+
this._purchaseOrderErrorMessage = selectedAddressResult.error;
325+
return;
326+
}
327+
324328
const poInput = this.getComponent('[data-po-number]');
325329
// Make sure that PO input is valid first
326330
if (
@@ -337,7 +341,7 @@ export default class PaymentMethod extends LightningElement {
337341
setPayment({
338342
paymentType: this.selectedPaymentType,
339343
cartId: this.cartId,
340-
billingAddress: selectedAddress,
344+
billingAddress: selectedAddressResult.address,
341345
paymentInfo: paymentInfo
342346
}).then(() => {
343347
// After making the server calls, navigate NEXT in the flow
@@ -347,6 +351,11 @@ export default class PaymentMethod extends LightningElement {
347351
this._purchaseOrderErrorMessage = error.body.message;
348352
});
349353
} else {
354+
if (selectedAddressResult.error) {
355+
this._creditCardErrorMessage = selectedAddressResult.error;
356+
return;
357+
}
358+
350359
// First let's get the cc data
351360
const creditPaymentComponent = this.getComponent(
352361
'[data-credit-payment-method]'
@@ -367,7 +376,7 @@ export default class PaymentMethod extends LightningElement {
367376
setPayment({
368377
paymentType: this.selectedPaymentType,
369378
cartId: this.cartId,
370-
billingAddress: selectedAddress,
379+
billingAddress: selectedAddressResult.address,
371380
paymentInfo: creditCardData
372381
}).then(() => {
373382
// After making the server calls, navigate NEXT in the flow
@@ -379,6 +388,23 @@ export default class PaymentMethod extends LightningElement {
379388
}
380389
}
381390

391+
/**
392+
* @returns The selected billing address in an object { address: <the selected billing address> } or
393+
* { error: <the error message> } if the field is required but missing. It can return an empty
394+
* object if there is no billing address and it's not a required field.
395+
*/
396+
getBillingAddress() {
397+
if (!Array.isArray(this._addresses) || !this._addresses.length) {
398+
if (this.billingAddressRequired) {
399+
return { error: 'Billing Address is required' };
400+
}
401+
} else {
402+
return { address: this._addresses.filter(add => add.id === this.selectedBillingAddress)[0] };
403+
}
404+
405+
return {};
406+
}
407+
382408
getCreditCardFromComponent(creditPaymentComponent) {
383409
const cardPaymentData = {};
384410
[

0 commit comments

Comments
 (0)