Salesforce Commerce Cloud Shop API Order status update fails - salesforce-commerce-cloud

I have a question about the update of the status of an order.
I create the basket using OCAPI and then I can successfully create an order with
https://mydomain/dw/shop/v21_10/orders (POST)
Order is fine. All data are there.
Now the order has status CREATED and I want to change it to OPEN using the Shop API again.
https://mydomain/dw/shop/v21_10/orders/MyOrderNumber (PATCH)
This is the message I receive
{"_v":"21.10","fault":{"arguments":{"statusFrom":"CREATED","statusTo":"OPEN"},"type":"StatusTransitionNotPossibleException","message":"The status transition from 'CREATED' to 'OPEN' isn't possible."}}
While if I try to make the same transition in Business Manager it works perfectly.
Anyone knows why?

The reason you can't transition the order from CREATED to OPEN is because there is a step in between.
Unfortunately, this is poorly documented in OCAPI docs, but we can see a clearer picture if we look at the DW API docs which explain in more detail.
A bit of background
First, notice the description of the PATCH /orders/{order_no} endpoint:
same status transitions are possible as for dw.order.Order.setStatus(int status) plus CREATED to FAILED)
Okay, so it follows the DW API rules. Let's take a look at the Order.setStatus() method (emphasis mine):
This method does not support order statuses ORDER_STATUS_CREATED or ORDER_STATUS_FAILED. Please use OrderMgr.placeOrder(Order) or OrderMgr.failOrder(Order).
So this is telling us that we can't move an order out of CREATED status except by either placing it or failing it. If we take a look at the documentation for OrderMgr.placeOrder(order), it corroborates this:
This method places an order and is usually called after payment has been authorized. The specified order must be in status CREATED, and will be set to status NEW.
Now back to OCAPI
Now we know that OCAPI generally follows the same rules as the DW API when it comes to transitioning order statuses. (with the exception of CREATED -> FAILED)
So how do we go about placing an order with OCAPI?
With OCAPI, you can place an order by calling POST orders/{order_no}/payment_instruments which will trigger the following hooks:
Authorize the payment with either dw.order.hooks.PaymentHooks.authorizeCreditCard or dw.order.hooks.PaymentHooks.authorize, depending on the payment type
Place the order with dw.ocapi.shop.order.afterPostPaymentInstrument
On success of both those hooks, your order will now be in NEW status, and ready to be transitioned into OPEN.
This discussion is on the same topic, although talking about the controller context, not OCAPI.
So, even though business manager lets you get away with stuff (I assume so that admins can override things where necessary), in the context of OCAPI or a controller, the order has to follow the regular placement steps.

Related

GA3 Event Push Neccesary fields in Request

I am trying to push a event towards GA3, mimicking an event done by a browser towards GA. From this Event I want to fill Custom Dimensions(visibile in the user explorer and relate them to a GA ID which has visited the website earlier). Could this be done without influencing website data too much? I want to enrich someone's data from an external source.
So far I cant seem to find the minimum fields which has to be in the event call for this to work. Ive got these so far:
v=1&
_v=j96d&
a=1620641575&
t=event&
_s=1&
sd=24-bit&
sr=2560x1440&
vp=510x1287&
je=0&_u=QACAAEAB~&
jid=&
gjid=&
_u=QACAAEAB~&
cid=GAID&
tid=UA-x&
_gid=GAID&
gtm=gtm&
z=355736517&
uip=1.2.3.4&
ea=x&
el=x&
ec=x&
ni=1&
cd1=GAID&
cd2=Companyx&
dl=https%3A%2F%2Fexample.nl%2F&
ul=nl-nl&
de=UTF-8&
dt=example&
cd3=CEO
So far the Custom dimension fields dont get overwritten with new values. Who knows which is missing or can share a list of neccesary fields and example values?
Ok, a few things:
CD value will be overwritten only if in GA this CD's scope is set to the user-level. Make sure it is.
You need to know the client id of the user. You can confirm that you're having the right CID by using the user explorer in GA interface unless you track it in a CD. It allows filtering by client id.
You want to make this hit non-interactional, otherwise you're inflating the session number since G will generate sessions for normal hits. non-interactional hit would have ni=1 among the params.
Wait. Scope calculations don't happen immediately in real-time. They happen later on. Give it two days and then check the results and re-conduct your experiment.
Use a throwaway/test/lower GA property to experiment. You don't want to affect the production data while not knowing exactly what you do.
There. A good use case for such an activity would be something like updating a life time value of existing users and wanting to enrich the data with it without waiting for all of them to come in. That's useful for targeting, attribution and more.
Thank you.
This is the case. all CD's are user Scoped.
This is the case, we are collecting them.
ni=1 is within the parameters of each event call.
There are so many parameters, which parameters are neccesary?
we are using a test property for this.
We also got he Bot filtering checked out:
Bot filtering
It's hard to test when the User Explorer has a delay of 2 days and we are still not sure which parameters to use and which not. Who could help on the parameter part? My only goal is to update de CD's on the person. Who knows which parameters need to be part of the event call?

Validate Command in CQRS that related to other domain

I am learning to develop microservices using DDD, CQRS, and ES. It is HTTP RESTful service. The microservices is about online shop. There are several domains like products, orders, suppliers, customers, and so on. The domains built in separate services. How to do the validation if the command payload relates to other domains?
For example, here is the addOrderItemCommand payload in the order service (command-side).
{
"customerId": "CUST111",
"productId": "SKU222",
"orderId":"SO333"
}
How to validate the command above? How to know that the customer is really exists in database (query-side customer service) and still active? How to know that the product is exists in database and the status of the product is published? How to know whether the customer eligible to get the promo price from the related product?
Is it ok to call API directly (like point-to-point / ajax / request promise) to validate this payload in order command-side service? But I think, the performance will get worse if the API called directly just for validation. Because, we have developed an event processor outside the command-service that listen from the event and apply the event to the materalized view.
Thank you.
As there are more than one bounded contexts that need to be queried for the validation to pass you need to consider eventual consistency. That being said, there is always a chance that the process as a whole can be in an invalid state for a "small" amount of time. For example, the user could be deactivated after the command is accepted and before the order is shipped. An online shop is a complex system and exceptions could appear in any of its subsystems. However, being implemented as an event-driven system helps; every time the ordering process enters an invalid state you can take compensatory actions/commands. For example, if the user is deactivated in the meantime you can cancel all its standing orders, release the reserved products, announce the potential customers that have those products in the wishlist that they are not available and so on.
There are many kinds of validation in DDD but I follow the general rule that the validation should be done as early as possible but without compromising data consistency. So, in order to be early you could query the readmodel to reject the commands that couldn't possible be valid and in order for the system to be consistent you need to make another check just before the order is shipped.
Now let's talk about your specific questions:
How to know that the customer is really exists in database (query-side customer service) and still active?
You can query the readmodel to verify that the user exists and it is still active. You should do this as a command that comes from an invalid user is a strong indication of some kind of attack and you don't want those kind of commands passing through your system. However, even if a command passes this check, it does not necessarily mean that the order will be shipped as other exceptions could be raised in between.
How to know that the product is exists in database and the status of the product is published?
Again, you can query the readmodel in order to notify the user that the product is not available at the moment. Or, depending on your business, you could allow the command to pass if you know that those products will be available in less than 24 hours based on some previous statistics (for example you know that TV sets arrive daily in your stock). Or you could let the customer choose whether it waits or not. In this case, if the products are not in stock at the final phase of the ordering (the shipping) you notify the customer that the products are not in stock anymore.
How to know whether the customer eligible to get the promo price from the related product?
You will probably have to query another bounded context like Promotions BC to check this. This depends on how promotions are validated/used.
Is it ok to call API directly (like point-to-point / ajax / request promise) to validate this payload in order command-side service? But I think, the performance will get worse if the API called directly just for validation.
This depends on how resilient you want your system to be and how fast you want to reject invalid commands.
Synchronous call are simpler to implement but they lead to a less resilient system (you should be aware of cascade failures and use technics like circuit breaker to stop them).
Asynchronous (i.e. using events) calls are harder to implement but make you system more resilient. In order to have async calls, the ordering system can subscribe to other systems for events and maintain a private state that can be queried for validation purposes as the commands arrive. In this way, the ordering system continues to work even of the link to inventory or customer management systems are down.
In any case, it really depends on your business and none of us can tell you exaclty what to do.
As always everything depends on the specifics of the domain but as a general principle cross domain validation should be done via the read model.
In this case, I would maintain a read model within each microservice for use in validation. Of course, that brings with it the question of eventual consistency.
How you handle that should come from your understanding of the domain. Factors such as the length of the eventual consistency compared to the frequency of updates should be considered. The cost of getting it wrong for the business compared to the cost of development to minimise the problem. In many cases, just recording the fact there has been a problem is more than adequate for the business.
I have a blog post dedicated to validation which you can find here: How To Validate Commands in a CQRS Application

FB Ads API status , effective_status and the ads actual status

From the ads api doc it says
effective_status enum {ACTIVE, PAUSED, DELETED, PENDING_REVIEW,
DISAPPROVED, PREAPPROVED, PENDING_BILLING_INFO, CAMPAIGN_PAUSED,
ARCHIVED, ADSET_PAUSED} The effective status of the ad. The status
could be effective either because of its own status, or the status of
its parent units.
status enum {ACTIVE, PAUSED, DELETED, ARCHIVED} The configured status
of the ad. The field returns the same value as 'configured_status',
and is the suggested one to use.
BUT, the problem is unless the advertiser actively stops or pauses or deletes an advert or campaign the ad's status is always (as far as I can see in the aforementioned cases) ACTIVE. Am I wrong?
Secondly, does anyone know what the column on the Ads manager interface called "Delivery" is? It has values like "Completed" , "Not Delivering" etc.
Is there any way I can get this information from the API?
The field called 'delivery' in Facebook's UI is not a single field returned by the UI, but is based on examining the status, start/end dates, etc of the ads–you could replicate this yourself by examining the ads and their parent objects.
I'm not sure I understand what you're saying about "configured and effective status": if an ad was paused, both its effective and configured status should be PAUSED. If, for example, an ad's Ad Set was set to paused, the ad's configured status would remain ACTIVE but its effective status would be ADSET_PAUSED.
How is the status computed?
When you give an Ad a status via the API you are setting its configured_status. This will update to whatever status you give it ACTIVE, PAUSED, etc.. And this value should reflect immediately in the configured_status parameter via a GET request to the object. The configured_status parameter will show whatever value you last set it too regardless of the parent status.
With that being said, if you have an ACTIVE ad that is nested under a PAUSED adset it will inherit the PAUSED status and that will reflect via the effective_status parameter. You can update the status of an Ad regardless of the status of the adset. It will only inherit the status if the parent is PAUSED to prevent spending.
As status will inherit from the parent object, it is most likely disabled. The effective_status reflects the current status of the object which may be overridden by its parent. More info can be found here
NOTE: I just posted the documentation for the Ad object but this applies to Adset objects as well
The configured_status is synonymous to the status parameter and is what you should set when updating the Ad.
About what the column on the Ads manager interface called "Delivery" is?
According to Facebook, the new feature identifies under-delivering ad sets and explains why the under-delivery is happening and highlights suggestions for specific actions an advertiser can take to make their ad more competitive at auction – in-turn helping them to increase the performance of their advert.
Advertisers can find feedback relating to their ads in the “Delivery” column at the campaign and ad set level, and also under the “Tools” standalone tab in Facebook Ads Manager.
Check these article this might help you to give insights into "Delivery":
In Facebook Power editor
In Facebook Ads Manager
P.S Some things you only learn by practicing and trying during development process you cannot always depend on Documentation.
Hope this helps!!!!

PayPal PayFlow with MVC3 ASP.NET

Hi I was using this article
http://www.codeproject.com/Articles/152280/Online-Credit-Card-Transaction-in-ASP-NET-Using-Pa?msg=3753796#xx3753796xx
to understand the PayFlow Transaction Process and how to develope it.
After doing some successful tests from the example, I had some doubts about how I should be developing it for the release version.
1.- I'm planning to use the SDK methods and NVP call just like in the example for the release version. However, I don't know if I should be using something more like secure certificates or services call (I tried calling the wsdl service from .Net Wizard but I couldnt find any service that had to do with PayFlow Transactions).
2.- Also, in the PDF:
https://cms.paypal.com/cms_content/US/en_US/files/developer/PP_PayflowPro_Guide.pdf
There are some examples, like the one in page 29, that state:
//Typical Sale Transaction Parameter String
//The following is a typical PARMLIST string passed in a Sale transaction.
"TRXTYPE=S&TENDER=C&USER=SuperUser&PWD=SuperUserPassword&VENDOR=SuperUser&PA
RTNER=PayPal&ACCT=5105105105105100&EXPDATE=1209&CVV2=123&AMT=99.00&FIRSTNAM
E=John&LASTNAME=Smith&STREET=123 Main St.&CITY=San
Jose&STATE=CA&ZIP=12345&COMMENT1=Reservation&INVNUM=1234567890&PONUM=C12345
&CVV2=567&VERBOSITY=MEDIUM"
//Note that, besides the required parameters that you pass in a Sale transaction, this string
//includes other typical parameters. The COMMENT1 (and COMMENT2) fields help to track
//transaction information. The customer’s street address (STREET) and zip should be passed to
//use address verification service. CVV2 is needed for card security code validation.
What I dont understand in that example is why is using the CCV2 parameter twice. Also, I dont know what the INVNUM and PONUM parameters mean. Furthermore, I know the test will be successful if I dont pass the CCV2 (security code) parameter and the adress parameters, but arent these mandatory? It gets me a bit confused, since for the DirectPayment Service, they are.
3.- In the PDF, there is a section called "Submitting Purchasing Card Level 2 and Level 3 Transactions" in page 99. In page 100, it says:
//Level 2 and Level 3 data is generally considered non-financial data. Lack of adequate data
//may cause a transaction to be downgraded.PayPal generally requires up to Level 2 information in
//an Authorization transaction followed by additional Level 3 data in the associated
//Delayed Capture transaction. A Sale transaction should include all Level 3 data
//since it is authorized and later settled.
Does this means that I "Need" to use more parameters than the required ones for a Sale transaction; otherwise, the transaction might be downgraded?
1) PayPal provides PayFlow documentation that covers all of that. You'll basically need to send the same login credentials used at manager.paypal.com along with your API requests.
2) I think that's just a mistake that they have the CVV2 parameter included twice. You only want to include it once. The documentation I linked to before will cover what all the request parameters mean, but the INVNUM is what you can use to track your own invoices within the PayFlow/Paypal system. PONUM is similar, but would be a PO number instead of an invoice number. You could search on these values in the future if you need to find them in the PayPal system.
With both PayFlow and Direct Payment, the requirement of CVV2 and a matching billing address depends on your account's Fraud Filter settings. If you've set it up to require them then you'd get an error without it. If it's setup to accept failures/mis-matches then it'll do so accordingly.
3) No, you won't need to worry about this.

asp.net mvc 3 - sending an email and getting the return for validation a task (registration, form validation...)

I am having a register form that user fill in, once the form fill in, the registration is postponed till the user recieve an email to check that his email is ok, then when he reply the email, the registration is fully proceed.
I would like also the process to be automatic, without the need for the user to entered any number ect, just the need for him to click on the email to confirm, and automatic on my side too.
I want the process to be available to some others task than the registration process as well if possible.
Do I need to do all way check/123456 with the 123456 generated or is there a better way to do, a component, nuget that can do the job ? you experiences return would be helpful
thanks
You appear to be on the right track.
I do a similar thing quite often. It isn't generic since I do not need it but you can change that quite easily.
Once a user registers I send an activation e-mail that contains a link that when clicked navigates to something such as http://domain/member/activate/id where the id is a GUID. That is all I need. I look up the member id and activate it. Chances of someone guessing a new member's id are rather slim and even if they do it is very far from a train smash.
From what I can tell you need something more generic and a bit more security. You could always create some key (like a new GUID) that you store along with the user and then the activation calls: http://domain/member/activate/id?key={the guid}. You could even encrypt the key. But that is up to you.
For something that can be re-used and is more generic you could create an activation component that contains a list of activation ids. But to then activate a specific type of entity (such as user registration or form validation) you would need to have a way to perform that on the back-end. For example, when you call http://domain/activation/activate/id internally is looks up the id and gets the type. The activation request is, of course, created when, e.g., your user registers. You would probably want to store some expiry/timeout since a user may never activate.
For each type you could have an activation mechanism on the relevant controller: member/activate/key or formvalidation/activate/key. So when you activation controller receives a request to activate it has a list of routes conigured per type and the navigates to the relevant route to perform the 'actual' activation.
Another option is to have an in-process component perform activation e.g.: an IActivator interface implemented by a MemberActivator or FormValdationActivator and then have an IActivatorProvider implementation that gives you the relevant provider based on a type (.NET Type or a string type you provider --- that's up to you).
You could even pass an ActivationRequestCommand along to a service bus endpoint if you are so inclined.
So you have many options. HTH
If you are a developer I suggest you at least try to start with the code... then ask again if you get stuck providing a sample of what you've done.
What you are looking to do is basically use a temporary url that posts to a page to complete the registration...

Resources