I have a custom plugin that calls an API and adds some additional things to my orders at Woocommerce platform.
I had three scenarios before:
first time purchase, uses data submitted from the checkout form fields is used, e.g., $_POST['account_phone'], and everything went fine
subsequent purchases used the same principle
renewals used the order data from the initial orders, and acted like a single purchase is made
Now, the API has changed a bit and several new methods are available, which changes the scenario options above:
first time purchases go into two categories, new users at the API site, and existing users at the API site but new to this platform
remaining is the same
I have issue with the purchases for existing users of this site. First time purchase sends a request to the API, using the POST parameters. However, if a user is already registered, those parameters, like his cell phone number, should be read from the billing data he/she already entered. Thus, I need a way to tell the WooCommerce is this new user trying to buy something and registering, or that this is an already existing user that has his or her data entered. I can get this data from the initial order, or user's billing info, but can't figure out how to check what type of order is it and where WooCommerce should get those values from.
Thanks!
Managed to solve this via another way. The $fields['account']['account_phone'] was shown only during the registration, and simple change of that to $fields['billing']['account_phone'] makes that field "belong" to billing info, which is always shown, which is very convenient and makes no difference later when I check for input there.
Related
I'm confused by the array of Paypal APIs and options out there. Can someone help me to identify a good starting point for a virtual/digital product option that can have some custom meta data associated with it? Here are my requirements:
I'm selling in-app credits/currency
I'm using PHP to integrate with Paypal
Each purchase must be able to attach some data (for example, a user ID and a product ID from my database) that will be passed back to me so I can identify which user purchased which product, so once it is verified with Paypal, I'll know how to give the digital product to the buyer.
I assumed that "Digital Goods for Express Checkout" would do the trick, since it seems designed for online/virtual/digital types of products. However, I'm having trouble finding a way to pass through the user ID and product ID with this option. I also looked at the example and library at https://github.com/thenbrent/paypal-digital-goods-php-examples but I don't see an obvious way attach this dynamic meta data.
Thanks for any help!
Actually you only want one id. Nothing more is needed. Before processing the order, you bind the id with your meta data (in a database like MySQL).
Then in the listener you can pull out the data using the id.
Hope it helped
I've built a web application and I am looking to integrate cardsave's direct payment API into the application. I was wondering if anyone had any advise on the best way to do this.
Cardsave provide standard code for integrating: Download Gateway Integration Pack ZIP file
When a payment is made I need to store the CrossPaymentsReference and payment amount in my database, the rest I will leave to cardsave's api I have thought of a couple of solutions which should potentially work:
1) Using Views for all of the code and on sucessful payment and use Ajax to update the database with the crossPaymentReference and payment amount on sucessfull completion, because it involves minimal editing of the code, but does have a minor security risk because it sends the reference at the client end.
2) Create a library with the payment system class, put the preprocess payments and process payment code into a controller and copy the form into a view, and just a have a small model to update the database on sucessfull payment's. (I'm guessing this is the best way.)
3) Edit everything and build an MVC version of the code
My latest project runs on CI 2.0. I’ve integrated a payment system such as Card Save with success (in my case I use Ogone, which is a Belgian company).
Below I’ve detailed a bit how I implemented the order and payment system.
The advice I can give you is the following.
Keep your products, orders and payments in separate tables.
Link products to orders via a reference table (don’t store e.g. a list of product ID’s in a field in the order)
Allow that a payment can only have one order, but an order can have multiple payments (but only one paid). This way when a payment fails (e.g. the user pressed cancel on Card Saves payment page), you can just create a new payment on your side and let the user retry (unless Card Save accepts that you do 2 payment request with the same payment ID).
Make a separate library (not controller) that handles successfully paid orders. This library would e.g. activate a subscription that the user bought, or make a work order for someone to ship the products. By keeping it in a separate library you can extend its functionality (e.g. if for a specific product you would need to do something new) without touching at your payment logic (thus preventing heavy retesting).
Generate hashes when posting data, or redirecting users to checkout pages, pages that prepare the payment and recalculate the hashes each time to prevent that someone tampered with the data you posted or that is in the URL.
Make sure everything works without AJAX and add AJAX afterwards.
Basically the ordering process I came up with is divided as follows:
User adds services (I don’t sell physical products) to basket (using a modified version of CI’s shopping cart)
When done user clicks “Order products” which does a POST to the controller Place_order. The controller Place_order does the following things:
Check if the user is still logged in (in my case everyone needs to register before)
Get the products that are in the shopping cart and checks if they actually exist in the database (you never know)
Create a new order in the database and add the products to the order in the DB
Place_order doesn’t output anything, but redirects the user on success to a controller Checkout. Here I don’t use POST. This way you can reuse the URL (e.g. if the user decides to stop, he can continue the payment later). The URL contains the order ID and a hash.
The Checkout controller does the following
Recalculate the hash to see if no one tampered with the URL
Check if the order exists and isn’t paid yet
Check if the order belongs to the user logged in
Create the payment if it doesn’t exist yet
Show a view with a button “Cancel order” and “Pay order”. This is actually a form that contains in a hidden field the payment ID and a hash of the payment ID.
When clicking “Pay order”, a POST is done to a controller Pay_order. I don’t use GET, because I want that users only come on this page by posting data that was set by the Checkout controller. If they use GET to come on the page an error is thrown. This controller does the following:
Recalculate the hash to see of no one tampered with the posted data
Check if the payment exists and is not yet paid
If all is OK, compose the view that contains the necessary info to be posted to the payment service
Show the view.
When the user presses “Go to payment service” all data is posted to Ogone where the user executes the payment
When the payment is completed (correct or not) Ogone redirects the user back to me to a controller Payment_successfull or Payment_other (for errors etc). In the Payment_succesfull I call a library Purchase_activator which takes the payment ID as input. This one looks up the order and activates the services the user just paid. In the other case (on error) the user is shown a view with the correct error message and an option to retry or cancel.
I have 2 pages for collecting payments for an online services business.
1st form collects basic information (name, address, dob, etc) from buyers and inserts into a mysql table
when 1st page is submitted it forwards user to a page where they can select service packages which is linked to paypal payment gateway.
The scenario that i am facing is, after submitting the first page (data gets inserted to mysql) but lets say user decides not to pay for packages on 2nd page, i have redundant data in mysql table
Is there a way to manage this? should i combine payment collection + information collection in one page?
please advise,
If you don't want a customer to enter twice his personnal/shipping information, implement an account system, where a user creates an account with email/password, and his personnal/shipping information is linked to that account.
If you don't want an account system, you can make the folowing: when a user comes back, and if he already entered shipping information and didn't complete she payment, suggest him to reuse the previous information (by his cookie for example).
But anyway, there is not much you can do against a user that chooses to re-enter information (or create multiple accounts)
You have no redundant data in your database, you have potential customers that are interested in your product - but somehow didn't complete the payment step.
You could contact them later - having their email - and do some aftersales.
What you can do is set a timestamp on the data entered in the first page. Periodically, have a script run through the database and remove entries that are older than the last sweep. For example, if you run it daily, remove everything older than 2 days. Hourly, everything more than 2 hours, etc.
I'm working on a project that ties into an API and uses virtuemart. Basically a user can buy time for a phone card. the few things I need help with are:
A) can/how can I create a custom php function once the user signs up. For instance, the user adds Items to the cart and proceeds to checkout. once the user clicks checkout they need to create an account, after they create an account is there an area in this process that allows for a custom function so that I can tie the creation of the account to an API?
B) same as above but after checkout. After the checkout goes through, how can I make it so the new values are sent to the API? Is there an area in the files that allow for custom functions here.
C) Lastly is it possible to add more options the the virtuemart customer account maintnance screen. I want an option that will tie into the API and show them exactly how much time the have left for their phone card. This information will be provided by the api.
All of these things can be achieved with a System Plugin. You would simply look for the right url, get any information from the result screen with regex, call your API and insert any changes back into the screen.
I'm not specifically aware of any VM functions for this, but as VM is in flux with Version 2 getting closer, it may not be a good time for any such investment in any case.
I have a problem that i seems can't figure out properly.
I got a website where you can pick some offer and buy it.
The steps for this procedure is:
1) Customer pick offer (index.php) he like and proceed to (buy.php) page
2) At (buy.php) page he selects quantity and payment method
3) When customer presses buy he is redirected to (payment.php) where all data is verified again and doing some database recording. Payment.php page processes user to selected payment gateway (out of my website).
So the problem is that i can swap $_POST data from buy.php page to payment.php and payment page would think that data is correct.
Before i was simply checking if price that comes to payment page is one of allowed prices in my $array and i had no problems with this. But now i offer a discounts and i can not tell if amount coming in is indeed correct.
How usually all this is processed? I'm new to working with payments.
Thanks.
The usual way payment providers do this, is the following.
You have a form that will result in a POST array.
add one field to this array with a hash. Make this hash from the string as follows:
Define a secret string (some sort of a 'salt', but different)
Sort all your POST keys alphabetically.
Make a string like this:
key=value.secretString.key2=value2.secretString ... etc
hash the string and send it in the post.
(do NOT send, show or reveal your secret string, obviously)
Now when you receive the POST, you can use your secret string to recreate the hash that should accompany it, and compare it to the hash you got (also in the post ofcourse, obviously don't hash that too). If it is equal, the values where not tampered with. If it isn't you should reject the payment.
Because you also include a date, a user/orderID etc in your post, it cannot be changed for the post of another order. Changing one of the values in the post would also mean the HASH has to be changed, but as the user can't create it, this will not do.
Try a db table of product id's with prices and a table of discounts with the amount (or percent). When the users submits an order, send the ids of products with their respective quantities along with the ids of any discounts to the payment script. Let it handle the final price calculation.