Enquiry about custom checkout flow in spartacus - spartacus-storefront

I have some questions around checkout in spartacus. These are the 2 scenarios that I need to implement for one of my project:
Spartacus version: 4.3
Checkout Steps:
Checkout Bundle (custom step) >> Shipping Address >> Delivery Address >> Payment >> Review Order
For a certain product, said Product A. It will skip the entire checkout steps and go straight to Review Order step.
For a certain, said Product B. It will have bundle step and based on the bundle selection, it will determine if it required to go to Payment Step.
Issues:
After I have redefined the steps and create custom guard, it still doesn’t allowed me pass to the review-order step. For some reason the Spartacus libraries check if the shipping, deliver or payment Info have existed in the cart before proceed to the review-order step. Is there any work around this issue?
Snapshot of the code below:
// default-checkout.config.ts
export const checkoutConfig: PSCheckoutConfig = {
checkout: {
steps: [
{
id: 'bundle',
name: 'checkoutProgress.bundle',
routeName: 'checkoutBundle',
type: []
},
{
id: 'shippingAddress',
name: 'checkoutProgress.shippingAddress',
routeName: 'checkoutShippingAddress',
type: [CheckoutStepType.SHIPPING_ADDRESS],
},
{
id: 'deliveryMode',
name: 'checkoutProgress.deliveryMode',
routeName: 'checkoutDeliveryMode',
type: [CheckoutStepType.DELIVERY_MODE],
},
{
id: 'paymentDetails',
name: 'checkoutProgress.paymentDetails',
routeName: 'checkoutPaymentDetails',
type: [CheckoutStepType.PAYMENT_DETAILS],
},
{
id: 'reviewOrder',
name: 'checkoutProgress.reviewOrder',
routeName: 'checkoutReviewOrder',
type: [CheckoutStepType.REVIEW_ORDER],
},
]
},
};
// checkout.module.ts
ConfigModule.withConfig(<CmsConfig>{
cmsComponents: {
CheckoutProgress: {
component: PSCheckoutProgressComponent,
},
CheckoutBundle: {
component: PSCheckoutBundleComponent,
guards: [RequireBundleGuard],
},
CheckoutPaymentDetails: {
component: PSCheckoutPaymentDetailsComponent,
guards: [RequirePaymentGuard, CustomCheckoutStepsSetGuard],
},
CheckoutReviewOrder: {
component: PSCheckoutReviewOrderComponent,
guards: [CustomCheckoutStepsSetGuard]
},
},
}),
],

I discuss this question with our checkout experts in the team.
even if customer would like to combine multiple steps into a single step, the necessary info ( shipping, delivery and payment info ) still have to be generated via a single API call, as described in this note:
2998330 - SAP Commerce Cloud, single-page checkout via ycommercewebservices OCC APIs v2
Take Express checkout for example - it doesn't skip steps, but rather relies on pre-existing defaults in the user account.
We don't think there is a way that Spartacus can be configured to skip those checkout info requirements, other than potentially replacing services or something like that.
Moreover, from server implementation perspective, we don't even know if the backend will accept ootb to place an order with some info missing - this is something the customer can try to figure out with postman.
Bottom line, it does not sound like something that would work ootb and it probably requires customization. These are checkout customizations that customers would have to do themselves.
Again the source code in 2998330 - SAP Commerce Cloud, single-page checkout via ycommercewebservices OCC APIs v2 might be a good reference for start.

Related

Gridsome plugin-google-analytics tracking never show up on GA plateform

I have an issue with plugin-google-analytics
https://github.com/gridsome/gridsome/blob/master/packages/plugin-google-analytics/README.md
when i put my Google Analytics tracking Id in gridsome.config.js it do nothing on Google Analytics plateform. Same after two days.
i upload all my files on server but never show up..
What i missed?
module.exports = {
siteName: 'massivemedias',
plugins: [
{
use: '#gridsome/plugin-google-analytics',
options: {
id: 'G-NNQ12FXXX' //my tracking id
}
}
]
}
That plugin you mentioned works with the Universal version of Google Analytics (which is what has the ids in the format UA-XXXXXXXXX-X), like the example in your link:
module.exports = {
plugins: [
{
use: '#gridsome/plugin-google-analytics',
options: {
id: 'UA-XXXXXXXXX-X' // <-- Universal Analytics tracking ID
}
}
]
}
The code you entered in the example, G-NNQ12FXXX, refers to the new Google Analytics 4 which, being a different system from the previous one and does not work (yet) with that plugin.
So I suggest you to create a Universal Analytics type Property and use its ID (UA-XXXXX-X) with the plugin you indicated. You can find it by clicking on Show advanced options (when you create a new property):

CRYPTOGRAM_3DS – Why doesn't it work as the only option?

I'm trying to add Google Pay support to a website where we already have it working for a native app. The in-app implementation does not allow PAN_ONLY cards (due to high chargebacks), only CRYPTOGRAM_3DS. This works just fine.
When I configure the website to only allow CRYPTOGRAM_3DS, I can never get paymentsClient.isReadyToPay() to return true. I've tried different Android devices which are able to make in-app payments with no success. To be clear: If I allow PAN_ONLY then Google Pay works as expected and I can obtain tokens.
How can I troubleshoot the reason why this is happening? Does it work for anyone else if you remove PAN_ONLY from the setup config?
thanks!
CRYPTOGRAM_3DS refers to tokenized cards. That is, cards that have been added and stored on you Android device. These are the same cards that you can use to pay in-store (not in-app) with Tap and Pay.
If you are using CRYPTOGRAM_3DS only, this means that it will currently only work on a Android device where a user has saved a tokenized card.
I've put the following example together to demonstrate (make sure you test on a Android device with appropriate cards): https://jsfiddle.net/w5ptorbd/
<script src="https://unpkg.com/#google-pay/button-element#2.x/dist/index.umd.js"></script>
<google-pay-button environment="TEST"></google-pay-button>
const button = document.querySelector('google-pay-button');
button.paymentRequest = {
apiVersion: 2,
apiVersionMinor: 0,
allowedPaymentMethods: [
{
type: 'CARD',
parameters: {
allowedAuthMethods: ['CRYPTOGRAM_3DS'],
allowedCardNetworks: ['MASTERCARD', 'VISA'],
},
tokenizationSpecification: {
type: 'PAYMENT_GATEWAY',
parameters: {
gateway: 'example',
gatewayMerchantId: 'exampleGatewayMerchantId',
},
},
},
],
merchantInfo: {
merchantId: '12345678901234567890',
merchantName: 'Demo Merchant',
},
transactionInfo: {
totalPriceStatus: 'FINAL',
totalPriceLabel: 'Total',
totalPrice: '100.00',
currencyCode: 'USD',
countryCode: 'US',
},
};
button.addEventListener('loadpaymentdata', event => {
console.log('load payment data', event.detail);
});
button.addEventListener('readytopaychange', event => {
console.log('ready to pay change', event.detail);
});

PDP Custom Routes defined in a module not working

I'm following the Spartacus bootcamp sample for routing https://github.com/SAP/spartacus-bootcamp/tree/77b7474c9538eaa1032062ad3c6d461fb1fc7517/src/app/features/routing
My problem is when I have configured the custom PDP
imports: [
CommonModule,
// dependent module for semantic URLs like cxUrl
UrlModule,
// standard non-spartacus routes
RouterModule.forChild(staticRoutes),
// configure product routes
ConfigModule.withConfig({
routing: {
routes: {
product: {
paths: [
'product/:manufacturer/:firstCategoryName/:productCode/:prettyName',
'product/:manufacturer/:productCode/:prettyName',
'product/:productCode/:name',
],
},
},
},
} as RoutingConfig),
//code mapping in the routes
ConfigModule.withConfig({
paramsMapping: {
productCode: 'code',
},
} as RouteConfig),
The new PDP routes are never used in the Storefront. I can see in the browser console that the custom product properties firstCategoryName and prettyName are properly settled from the normalizers/converters of the sample...
Any insight what can be going on?
Thanks!
Fernando
I think it will also depend on whether/not the manufacturer property is populated as well. By default the manufacturer field is not requested in the productSearch OCC call, so will not be populated on the product object (see default-occ-product-config.ts in the Spartacus code) - this means that on product listing pages (category & search) those two paths will not resolve, and are therefore ignored.

How to change BaseStore from SAP Spartacus storefront

As Spartacus is for B2C process there is no any option to change BaseStore from storefront. I have a drop down for different countries and now want to change BaseSite from it.
So finally I made it working. I am storing baseSite to session if its changed from dropdown and if user is coming back reading it first from session.
here what you have to do to make it working:
Override BaseSite service and change initialize method similar to the initialize method of LanguageService. (which check if baseStore is stored in session )
Listen to SET_ACTIVE_BASE_SITE action and set payload to session. (again similar like activeLanguage effect in LanguagesEffects)
Now in B2cStorefrontModule config add your other sites as
B2cStorefrontModule.withConfig({
context: {
baseSite: ['electronics','mystore2','mystore-uk', 'mystore-canada'],
language: ['en'],
currency: ['USD']
}
So the main solution is, you listen to basestore change action and store the value to session and on page load you read basestore from session
I think you are looking for this. Check full code on Building the Spartacus Storefront from Libraries
B2cStorefrontModule.withConfig({
backend: {
occ: {
baseUrl: 'https://localhost:9002',
prefix: '/rest/v2/',
legacy: false
}
},
authentication: {
client_id: 'mobile_android',
client_secret: 'secret'
},
context: {
baseSite: ['electronics']
},
i18n: {
resources: translations,
chunks: translationChunksConfig,
fallbackLang: 'en'
}
}),

Payment token becomes undefined after the Apple Pay process

I am developing an Apple Pay with react-native. I configured everything and I used react-native-payment component. Here is my code:
onPressApplePay=()=>{
console.log("1- start Apple Pay");
if (!DataManager.getInstance().isConnected()) {
this.myAlert(I18n.t("NoInternetConnectionState"));
return;
}
const DETAILS = {
id: 'basic-example',
displayItems: [
{
label: 'items',
amount: { currency: 'EUR', value: '2' },
},
],
total: {
label: 'MyApp',
amount: { currency: 'EUR', value: '2' },
},
};
const METHOD_DATA = [{
supportedMethods: ['apple-pay'],
data: {
merchantIdentifier: 'merchant.com.myapp',
supportedNetworks: [ 'mastercard', 'visa'],
countryCode: 'IT',
currencyCode: 'EUR'
}
}];
const paymentRequest = new PaymentRequest(METHOD_DATA, DETAILS);
console.log("2- paymentRequest.show", paymentRequest);
paymentRequest.show()
.then((paymentResponse) => {
const { paymentToken } = paymentResponse.details; // On Android, you need to invoke the `getPaymentToken` method to receive the `paymentToken`.
paymentRequest.canMakePayments()
.then(canMakePayments => {
console.log("canMakePayments", canMakePayments);
console.log("paymentToken", paymentToken);
// Show fallback payment method
});
})
.catch((err) => {
console.log("4- err", err);
console.log("5- paymentRequest", err);
//alert("The apple pay cancel");
// The API threw an error or the user closed the UI
});
The problem is that as I try to execute the Apple Pay, it says that the 'Payment is not completed' and the token becomes undefined. Can you please ket me know where the problem might be hiden.
I should mention that I tried this code on a real device using both real card and sandBox and in all cases it was failed. Thanks in advance.
This component is also working with stripe and Braintree. The problem was that I needed to add a gateway and a public key which in my case it provided from stripe.
const METHOD_DATA = [{
supportedMethods: ['apple-pay'],
data: {
merchantIdentifier: 'merchant.yyyy.xxxx',
supportedNetworks: [ 'mastercard'],
countryCode: 'IT',
currencyCode: 'EUR',
paymentMethodTokenizationParameters: {
parameters: {
gateway: 'stripe',
'stripe:publishableKey': 'pk_test_XXXXXXX',
'stripe:version': '5.0.0' // Only required on Android
}
}
}
}];
Then I installed the following add on:
yarn add react-native-payments-addon-stripe
yarn add react-native-payments-cli
yarn react-native-payments-cli -- link stripe
(You also need the Carthage update there to make them work)
Then I made an account in stripe.com and use the publish key of that and finally it works!!
Also I have added paymentResponse.complete('success'); to show the successful payment at the end. Without that it sucks in a loop of waiting and finally shows 'Payment is not complete'.
Now I have a successful message with a nice token!
I should mention that in the case that you don't use stripe or Braintree, you will not see any token and it will be always undefined. It is natural, so don't worry. You just need to pass paymentResponse.details as a JSON to your bank provider and it will work. Because in that case the transactionid will be important which you have it.
After that, you go through these steps of installing from this link . You also need to do these steps regarded to certificates for Apple Pay:
1- First on your App ID in your apple developer account you should enable the Apple Pay with the merchant ID.
2- Then you need to ask from your bank for a certificate on you merchant which is a file that looks like this:
XXXXX.certSigningRequest.txt
3- Then select your app ID and go to Apple Pay section which was enabled in step one and upload the certificate there.
Done! Your Apple Pay will work.
The mention saved me! I didn't realize that it was normal the token would be nil if you aren't using Stripe/Braintree!