PayPal PayFlow with MVC3 ASP.NET - asp.net-mvc-3

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.

Related

Salesforce Commerce Cloud Shop API Order status update fails

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.

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

how can i implement recurring payment for payeezy in codeigniter?

I want to integrate recurring payment using Payeezy in codeigniter. I have implement the single time payment using curl and now i want to recurring payment with acknowledgement to update my DB.
I created a WordPress plugin for Payeezy that also handles recurring. You should be able to use the underlying PHP code for CodeIgniter.
https://wordpress.org/plugins/wp-payeezy-pay/
I can explain the process that will get you the least PCI compliance issues, and that's the token-based API.
1. Generate Token in Payment Form
So basically you'll use the Javascript API to generate your authorize token. An authorize token doesn't charge the card. It's for validating the card and returning a token for better PCI compliance. This API source code and explanation is here:
https://github.com/payeezy/payeezy_js
2. Post Form To Your Server for the Curl Call to FirstData
Then, once you have this token, you post it back to your controller file with a standard form post, but remove the name attribute on your credit card number and credit card CVC fields so that these do not post to your server. Note that you'll need to store this data (but not card number and CVC) because on refunds (and subscription cancellations) you'll need to reply back with the last purchase token, cardholder name, card type, card expiration date, amount spent, and currency code. You may wonder why FirstData/PayEezy is asking you to store cardholder name, card type, and card expiration date. Well, there's a perfectly good explanation for that. Your call center may need that detail for troubleshooting an issue over the phone with a customer. Also, you need that for refunds. And, most importantly, if you're doing a recurring subscription payment, your code needs to look at the expiration date ahead of time before charging because the API call will fail if the card is past expiration. Last, because you're not storing the credit card number and credit card validation (CVC) code, you're going to be in stronger PCI compliance.
From there, since you are already familiar with the Curl process for a single-purchase, it's just a minor single field change (transaction_type becomes 'recurring') in the Curl to do the recurring. For anyone not familiar with the Curl process, it's explained here:
https://developer.payeezy.com/payeezy-api/apis/post/transactions-4
Also, for those unfamiliar people, you'll need to read up on how FirstData/PayEezy wants you to send in the Curl request with a special header that includes Content-Type: application/json, apikey, token, Authorization, nonce, and timestamp. You can see more detail about that here:
https://github.com/payeezy/payeezy_direct_API/blob/master/payeezy_php/example/src/Payeezy.php
(What I did to make that code simpler was intercept the Curl calls from that script into a log file so that I could make it much more straightforward in a single function instead of breaking it up into all these little functions. That made it far easier to understand what was going on.)
3. Switching Curl Call for Recurring Payments
So, as you discovered in your Curl call, you saw how to do a one-time purchase by setting the transaction_type to 'purchase'. For doing recurring, you set transaction_type to 'recurring'. You have to do that from the start. So, if I'm selling something for $29.99 monthly, the very first month charge needs to still be set to type 'recurring', as would any subsequent month.
4. Your Responsibilities for Recurring Payments
Now, this is where everyone gets hung up because it's poorly documented unless you check the PayEezy Developer Support Forum. For subscriptions, PayEezy doesn't have a system for setting payment plans with varying durations, nor setting up automatic (set-it-and-forget-it) subscriptions for you. (I think I read that they have something experimental on Apple Pay, but nothing else yet.) So, to achieve this, you have 2 choices:
Use Chargify.com. Unfortunately, though, this increases CPA (Cost Per Acquisition) of your product or service. You'll have to factor that in if you want to use that. This basically is a SaaS service that you send the transaction to and they handle the automatic subscription plan for you against FirstData/PayEezy.
Roll your own cron job solution. To do this, you basically take the Curl code for a single transaction, and change the transaction type from 'purchase' to 'recurring'. (Do that from the start -- don't start with 'purchase' on a recurring charge.) From there, it's up to you with your own cron job to check for product or service expiration terms, and then send the API call back off to FirstData/PayEezy for charging that card again with the 'recurring' transaction_type.
On either of those options, the customer never gets asked to enter in credit card data past the first time unless their card expires or unless you have some problem billing that card (like insufficient funds).
Of course, doing your own cron job route for the recurring payment has implications you'll need to prepare for:
Add some failsafe code so that you prevent the possibility of duplicate transactions, such as a database field.
Add some failsafe code such that if you have cancelled a subscription, you won't charge them again.
Add some failsafe code such that if they cancel their subscription, yet purchase it again as a subscription at a later time, that you do charge them again and don't block it from your other failsafe code.
Add some sort of grace period on your product or service such that even if you "say" that the term expired, you have like a 2 day grace period so that your API has a chance to do a renewal.
It's probably a good idea to email the customer before their renewal period so that they can make certain they have money in their account and have a way to cancel that charge (like call your office or call center, or have a link to click where you provide a way to cancel).
If their card has expired before the renewal, and you detect that in the warning email that comes before renewal, then you'll want to let them know this.
If their card has been declined for any reason at the point of renewal, then you'll want to let them know this and give them a link to go through the cart again to buy it again, or some other way to save that transaction in your code.
How To Do Subscription Cancellations / Stop Recurring Payments
To stop a recurring payment, you treat it just like a refund on a single purchase, but use the transaction ID of the last purchase. This is documented with this Curl example here:
https://developer.payeezy.com/payeezy-api/apis/post/transactions/%7Bid%7D-0
Look under "Refund" and choose Token.

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...

Magento Payment flow

I am working on implementing a new payment module for Magento and want to understand the core concept behind this logic. I know I have to extend from Mage_Payment_Model_Method_Abstract or any of its children classes, but my problem is when to use and how to use capture and authorize methods in my model.
For example if I split the whole process in steps like this:
User comes to the shopping cart and choses lets say some payment method which is gateway.
The system intercepts the request, collects all submitted data and sends the user to the gateway url.
User places his order (or cancels) at the gateway site which sends information about it to my store.
My store does some more modifications to the order with the received data and saves the order with status completed or canceled.
Where in these steps will I have to use authorize and capture methods ? I would appreciate if someone could explain to me what authorize and capture means?
Here's the way I've always understood the concepts, and what you'll need to know to implement a payment module in Magento. Answers to your specific "where does this happen" are bolded below, although it's not quite as simple as you're hoping for.
Pre-internet, brick and mortar credit card transactions were a two stage process.
At the time of a sale, when the merchant took a consumer's credit card for a purchase they'd slide it through a point of sale device which would call into the credit card's central office and ask "is this card authorized for this network, and is this particular consumer's line of available credit large enough to allow this purchase".
If the purchase was accepted (as opposed to declined), the charge was said to be authorized. The consumer would take their product, and the point of sale system/cash-register would note that the transaction was authorized. Then, at the end of a the day, or the end of the week, at some other predetermined regular schedule, or when the owner decided to stop drinking, the merchant would go though all their authorized receipts and send another request to the central office to capture the funds from the authorized transaction. Capturing the funds is what puts money in the merchant's account.
This is still the model in use by most gateways, and is the domain model that Magento Inc. chose to implement for their payment modules.
The way things are supposed to run is, when a consumer reaches the final checkout steps in a system like Magento, Magento issues an authorization request to the gateway's API. If the transaction is successful, the order is accepted into the system, and a unique ID from the authorization request is stored. Next, when the consumer's goods ship, a store owner uses the Magento admin to create an invoice. The creation of this invoice issues a capture request (using a store id returned from the authorization request). This is where these method calls are issued in Magento.
However, things get tricky because every payment gateway interprets these concepts a little differently, and every merchant interprets their "don't capture until we've shipped" responsibilities differently. In addition to the scenario described above, payment modules have a system configuration value known as a Payment Action. This can be set to Authorize Only, which will implement the flow described above. It can also be set to Authorize and Capture, which will both authorize and capture a payment when the order is placed. It gets even more confusing because although the method is called Authorize and Capture, current versions of Magento will only issue the capture request when set in this mode (at least for Authorize.net), and Authorize.net will, internally, leave capture requests in an authorized but not captured state for most of the day. How Magento handles orders and payments and invoices is one area of the codebase that changes a lot from version to version.
So, the idea behind the Magento payment module system is to shield you from the Cluster F--- that is programming payment Gateway logic. In your authorize method you implement a call to your payment gateway's authorize API (or perform whatever checks and logic you want to happen at this point). This method is passed a payment object and an amount. If you make you request/perform-your-logic and determine it's invalid for whatever reason, you throw an Exception with
Mage::throwException('...');
This tells Magento the authorization failed, and it will act accordingly (show an error message, etc.). Otherwise, you set data members on the Payment object and issue a
return $this;
The data members are things you'll need later, when capturing the payment. Which brings us to the capture method of your Payment module. This method is also sent a payment object and an amount. In this method you issue your capture request. The payment object will have cc_trans_id data member
$payment->getCcTransId()
which will allow you to issue a capture against your gateway. This is one of the data members you're responsible for saving up in authorize. Again, if your code determines the capture has failed, you throw an exception. Otherwise, you return $this.
The authorize.net payment module has good examples of how this is done.
app/code/core/Mage/Paygate/Model/Authorizenet.php
For example, consider this part of the capture method
public function capture(Varien_Object $payment, $amount)
{
if ($payment->getCcTransId()) {
$payment->setAnetTransType(self::REQUEST_TYPE_PRIOR_AUTH_CAPTURE);
} else {
$payment->setAnetTransType(self::REQUEST_TYPE_AUTH_CAPTURE);
}
$payment->setAmount($amount);
$request= $this->_buildRequest($payment);
$result = $this->_postRequest($request);
//...
Here the capture method is checking if the payment has a cc_trans_id. Depending on the result, it sets anet_trans_type to either:
self::REQUEST_TYPE_PRIOR_AUTH_CAPTURE
self::REQUEST_TYPE_AUTH_CAPTURE
This value is then used by the API request object to send an API call for either
Capturing a pre-authorized transaction
Immediate capture

Resources