snowplow-archive / codeigniter-paypal-ipn

A CodeIgniter library for working with the PayPal IPN (Instant Payment Notification) service
111 stars 34 forks source link

Items with Same Name Error #15

Closed brwnll closed 11 years ago

brwnll commented 12 years ago

I am having an error with items having the same name (but different SKUs) are not being correctly added to the database on order extraction.

My use case is: The site offers multiple variations of a product, which is tracked by the SKU. So the order could look like:

"Rugged Mtn. Bike" sku: "MTNBIKE" qnty: 1 price: $100

"Rugged Mtn. Bike" sku: "MTNBIKE-RED" qnty: 1 price: $150

This results in only one item being added to the order items db table. But the totals of the transactions being correct.

If you have time, and an idea for a quick fix, please let me know, otherwise I'll do a branch and see if I can't put something together!

Thanks

alexanderdean commented 12 years ago

Hi smalldogs, sorry to hear you've been having an issue. I've doublechecked the code (https://github.com/orderly/codeigniter-paypal-ipn/blob/master/activerecord/libraries/PayPal_IPN.php lines 303-335) and I can't see anything that might be leading multiple variations of a product to be merged.

My immediate thought was: are you 100% sure that the order items are being merged by codeigniter-paypal-ipn, and not by your checkout process? It may be that only one order item is being transmitted by PayPal to codeigniter-paypal-ipn.

Let me know what you find out - if you want to show me any data relating to your problem, you can email me at alex@keplarllp.com.

brwnll commented 12 years ago

I was able to verify that PayPal is receiving the items correctly, all items appear correctly on the PayPal receipt/confirmation email.

My suspect is Ipn_order_model->saveOrder is overwriting it, believing the second item is an update to the first item.

Thoughts on adding item_number => $item['item_number'] to $orderItemQuery when checking for existing line items?

// Now let's save the order's line items
foreach ($orderItems as $item)
{
    // Define the order item query
    $orderItemQuery = array('item_name' => $item['item_name'],
                                         'order_id'  => $orderID);

    // Add the order ID and datestamp into the item to update/insert
    $item['order_id'] = $orderID;
    $item['updated_at'] = $upsertTime;

    // Now try to retrieve the order item
    $existingOrderItem = $this->db->get_where(self::ORDER_ITEM_TABLE, $orderItemQuery, 1, 0);

    // If the order item exists, update
    if ($existingOrderItem->num_rows() > 0)
    {
        $this->db->update(self::ORDER_ITEM_TABLE, $item, $orderItemQuery);
    }
    // Else insert the order item
    else
    {
        $item['created_at'] = $upsertTime; // Insert needs a created_at time as well
        $this->db->insert(self::ORDER_ITEM_TABLE, $item);
    }
}
alexanderdean commented 11 years ago

Sounds good - thanks for digging into this @smalldogs! I have merged your pull request, many thanks for that. Can we close this one now?