I'm working on a South African site and attempting to add PayPal support. I've run into a few issues and not sure if it's a configuration issue on my side or a problem with commerce_paypal. The South African Rand (ZAR) is not supported by PayPal so I'm using hook_commerce_paypal_wps_order_form_data_alter to change the currency and amount right before sending the data over to PayPal. I've added another field to the order called "foreign currency" where I save the USD amount so that I can verify later.
After verifying the IPN from PayPal for the payment my order is immediately marked as "completed". I was expecting to see the payment in the order but it shouldn't be marked as complete as the order total is say, R100 and the USD amount paid at PayPal is $12. In other words, there's no real verification that payment has been made in full. I was expecting it to work as follows:
1. The order review page lists all prices in ZAR
2. Alter the total on payment redirect to have a USD amount sent to PayPal
3. Customer pays on PayPal, IPN returned to Drupal
4. Order is listed as having had a payment made against it and triggers a rule (not sure which one yet)
5. Verify that the USD amount paid is equal to the amount stored in my orders "foreign currency" field.
6. Mark order status as completed.
Unless I've configured something poorly, it looks like anyone can alter the form values at the "Off-site payment redirect" (commerce_paypal_wps_order_form) part of the order checkout, change the amount_1 value to anything they please, pay that amount at paypal and have the order marked as complete. There doesn't appear to be any verification on the actual amount paid at paypal compared to the order total.
Do I need to add a rule myself to block order completion is the payment amount doesn't add up?
One last question.. why does this payment method have "terminal" set to FALSE? I've set it to TRUE just for my own testing.
Thanks for any help!
| Comment | File | Size | Author |
|---|---|---|---|
| #5 | paypal_ipn_currency_conversion.patch | 1.09 KB | jackbravo |
Comments
Comment #1
hadsie commentedOk, I think I've mostly figured this out now. I had set up another rule that changed the order status to "completed" when the cart checkout was complete. However, this shouldn't be the case if the order balance is not zero.
After I do the above steps, it looks like I'll need to add another payment transaction to the order of an amount in Rands so that the order balance hits zero and the order properly completes.
Comment #2
rszrama commentedWhat happens is upon payment completion, you'll get an IPN from PayPal verifying the payment amount. When that comes in, Commerce will create a completed payment transaction in whatever amount was actually paid. If the customer tried to scam you, the order balance would continue to be positive. This is why we advise sites not to take any irreversible fulfillment action prior to receiving a paid in full notification - this is facilitated by the "When an order is first paid in full" event. There's also an order balance comparison condition for use at other times. There should be more discussion of this in the queue.
Additionally, at least in 2.x (and I believe even before in 1.x), our modules facilitate the conversion of payment amounts into whatever you select as the default currency in your WPS configuration. This means all you really need to do is keep your currency info array up to date with the proper conversion rate from Rand to Dollars, and it should automatically be converted upon redirect to PayPal and when calculating the order balance.
I did just realize we'll need to store the currency conversion rate to ensure we can calculate the order balance properly if the conversion rate has changed from one day to the next. Added that to the Commerce roadmap for now.
Finally, the reason 'terminal' is set to FALSE is because technically speaking PayPal WPS isn't supposed to be used by a merchant on behalf of a customer.
Comment #4
jackbravo commentedHi
I have a store in Bolivia that sends payments to paypal. Like you said, we are handling the currency conversion (not with the multicurrency module but with two simple functions:
But the problem that I have is that the transaction is not triggering the "order is payed in full rule" because the function that calculates the balance of the order: [commerce_payment_order_balance](http://www.drupalcontrib.org/api/drupal/contributions!commerce!modules!p...) actually returns `FALSE` when you have amounts in more than one currency.
So, I have my prices in BOB. When going to paypal I see that the currency conversion is happening fine and I'm able to pay in USD in paypal. But when the IPN comes back I receive the payment in USD and no conversion is made back to BOB, they payment is stored in USD, so when the payment modules checks the balance to see if it needs to trigger the 'payed in full' rule it gets false instead of a balance of 0.
Comment #5
jackbravo commentedI found the issue, the module is using the function `commerce_currency_convert` when sending the request to paypal, but when receiving the response through the IPN it is not calling the conversion function.
Here is a patch to add that conversion.
Comment #6
jackbravo commentedI'm leaving this issue as closed and opened a new one here: https://www.drupal.org/node/2595243