Paypal IPN - store data on database, update and delete - php

I'm using this example to store in the database the info coming from PayPal, my problem is that the database create two records for the same sale, one with the status of 'Pending' and one with the status 'Completed', both for the same sale.
How can I change this part of the code so if there is a sale with the same 'txn_id' I just update the 'payment_status' row OR delete the whole thing before update it with the new info. Note that there is two rows that will be different, 'payment_status' and 'createdtime' .
function updatePayments($data){
global $link;
if(is_array($data)){
$sql = mysql_query("INSERT INTO `payments` (txnid, payment_amount, payment_status, item_name, receiver_email, payer_email, custom, itemid, createdtime) VALUES (
'".$data['txn_id']."' ,
'".$data['payment_amount']."' ,
'".$data['payment_status']."' ,
'".$data['item_name']."' ,
'".$data['receiver_email']."' ,
'".$data['payer_email']."' ,
'".$data['custom']."' ,
'".$data['itemid']."' ,
'".date("Y-m-d H:i:s")."'
)", $link);
return mysql_insert_id($link);
}
}
Database structure
CREATE TABLE IF NOT EXISTS `payments` (
`id` int(6) NOT NULL AUTO_INCREMENT,
`txnid` varchar(20) NOT NULL,
`payment_amount` decimal(7,2) NOT NULL,
`payment_status` varchar(25) NOT NULL,
`item_name` varchar(50) NOT NULL,
`receiver_email` varchar(50) NOT NULL,
`payer_email` varchar(50) NOT NULL,
`custom` varchar(25) NOT NULL,
`itemid` varchar(25) NOT NULL,
`createdtime` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

Create a UNIQUE INDEX on txn_id (if one doesn't exist already) and then use either INSERT ... ON DUPLICATE KEY UPDATE or REPLACE in place of your existing INSERT.
UPDATE
In your case, to add the unique index:
ALTER TABLE payments ADD UNIQUE INDEX (txnid);
Then, append to the end of your INSERT statement:
ON DUPLICATE KEY UPDATE payment_status = '".$data['payment_status']"'
If you want to delete the existing record and replace it with your new one, just change the word INSERT to REPLACE instead.

Related

Insert Data From One Table to Another Table and Add New Values

I have two tables.
Temporary table :
CREATE TABLE IF NOT EXISTS `temporary` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`FK_user` int(11) NOT NULL,
`FK_bin` varchar(50) NOT NULL,
`orderDate` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=35 ;
And orders table :
CREATE TABLE IF NOT EXISTS `orders` (
`id` int(11) NOT NULL,
`FK_user` int(11) NOT NULL,
`FK_bin` varchar(50) NOT NULL,
`orderNumber` varchar(11) NOT NULL,
`orderDate` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
I want to insert all values of Temporary table to Orders table and add orderNumber manually with this : uniqid(rand()) .
I have use INSERT INTO orders SELECT * FROM temporary WHERE FK_user = ?
But they don't work because orderNumber don't exist in Temporary table ...
How I can do ? please
Hoping i understand your questioin correctly. I think below query will help.
INSERT INTO orders(id , FK_user , FK_bin , orderNumber , orderDate)
(SELECT id , FK_user , FK_bin , uniqid(rand()) AS orderNumber , orderDate
FROM temporary WHERE FK_user = ?);
Use your function to generate order number in select statement as mentioned in above query.

mysql retrieve autoinc value for join insert

We have the following two tables:
CREATE TABLE IF NOT EXISTS `gp` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`amount` decimal(15,2) NOT NULL,
`user` varchar(100) NOT NULL DEFAULT '',
`status` tinyint(2) NOT NULL DEFAULT '1',
`ip` varchar(20) NOT NULL DEFAULT 'N/A',
`token` varchar(100) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;
CREATE TABLE IF NOT EXISTS `gp_logs` (
`id` int(11) NOT NULL,
`log` varchar(1000) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
We JOIN them, for statistics, but we do this rarely, since the data from the 2nd table is not used too often except when we need to verify things.
Considering that we have many queries per second, how can our query be optimized to use 1 INSERT query instead of two and to insert the correct id in the 2nd table (gp_logs) that was generated by the INSERT into table gp?
Right now, we do a combination of MYSQL with PHP:
mysqli_query($con,"INSERT INTO `gp` (amount,user) VALUES ('1234','1')");
$id = mysqli_insert_id($con);
mysqli_query($con,"INSERT INTO gp_logs(id,log) VALUES ('$id','some_data')");
We want to eliminate the requirement of PHP for getting the last inserted ID and to insert both entries by running a single INSERT query (with a JOIN).

MySQL ON DUPLICATE KEY two unique fields do not insert

I got this table
CREATE TABLE IF NOT EXISTS `set_indice_cuestionarios` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`cuestionario` int(11) NOT NULL,
`fecha` date NOT NULL,
`hora` time NOT NULL,
`aplico` varchar(100) NOT NULL,
`cliente` int(11) NOT NULL,
`tienda` int(11) NOT NULL,
`status` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `tienda` (`tienda`),
UNIQUE KEY `cuestionario` (`cuestionario`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
And this is my SQL sentence:
$sql_indice = "INSERT INTO set_indice_cuestionarios (cuestionario, fecha, hora, aplico, cliente, tienda) values('$cuestionario','$fecha','$hora','$aplico','$cliente','$tienda') ON DUPLICATE KEY UPDATE cuestionario = '$cuestionario', fecha = '$fecha', hora = '$hora', aplico = '$aplico', cliente = '$cliente', status = 0";
I want to Update a row if $tienda = tienda and $cuestionario = cuestionario and to Insert a new one if the any of the values doesn't match.
The Update is happening when both values match but when I only change $cuestionario it Updates the table, instead of inserting a new record, and when I only change $tienda it does the Insert. I have no idea what I' am doing wrong. Thank you in advance!

Advanced many2many query for MYSQL

I im trying to build a imagegallery where people have access to different groups and the groups decide what catalogues and images they are allowed to see.
I though many2many structure would be best for this.
So far, ive manage to build the database like this:
image (image_name, image_file, image_id)
catalog (catalog_id, catalog_name)
supplier (supplier_id, supplier_name)
user (name, user_id)
image2cataloge (image_id, catalog_id)
image2supplier (image_id, supplier_id)
catalog2supplier (catalog_id, supplier_id)
user2supplier (user_id, supplier_id)
So... that been said, saving images and making supplier (or group if you want), adding users to supplier and linking images to supplier and catalogues is no problem. Inserting is no problem.
But selecting the right images based upon the users supplier setting and catalog they are in is harder.
For example, I have a user with user_id 1, which have access to supplier_id 1. supplier_id 1 have access to view catalogue 1, which holds images with image_id 1 and 2.
But supplier_id 1 only have access to image_id 2.
All this settings are stored in the database. How do I do the select query?
This is what i've tested;
//$catalog_id is the catalog_id we are in
//$user_id is the current users user_id
$sql = "SELECT i.*
FROM image i, user u, catalog cat, supplier s, supplier2user s2u, supplier2catalog s2c, image2catalog i2c, image2supplier i2s
WHERE u.id = '".$user_id."'
AND s2u.user_id = '".$user_id."'
AND s2u.supplier_id = s.id
AND s2c.catalog_id = '".$catalog_id."'
AND i2c.catalog_id = '".$catalog_id."'
AND i2s.supplier_id = s.id
AND s2c.supplier_id = s.id
GROUP BY i.id
ORDER BY i.name ASC
But when ive added more than one image, all images are shown for all users in all catalogues.
EDIT (2010/02/05):
Okey, so I've figured out how to at least show correct images in correct catalog. I do this by doing following:
$sql = "SELECT i.*
FROM
image i
INNER JOIN image2catalog i2c
ON i.id = i2c.image_id
AND i2c.catalog_id = '".$pages_level_0[$i]['id']."'
GROUP BY i.id
;";
This let's me output the correct images that belongs in the catalog the user is visiting at the moment. Now I just need to edit this query to filter out all images the user doesn't have access to. I very grateful for any help you can provide!
EDIT 2010/02/09:
---
CREATION SCHEME
CREATE TABLE `user` (
`id` int(11) NOT NULL auto_increment,
`email` varchar(250) NOT NULL,
`password` varchar(50) NOT NULL
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `imagebank` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(250) character set utf8 NOT NULL default '',
`url` varchar(250) character set utf8 NOT NULL default '',
`childof` varchar(250) character set utf8 NOT NULL default '',
`hide` tinyint(4) NOT NULL,
`publishdate` varchar(14) NOT NULL,
`expiredate` varchar(14) NOT NULL,
`editdate` varchar(14) NOT NULL,
`editbygroup` varchar(250) NOT NULL,
`openby` varchar(250) NOT NULL,
`opendate` varchar(250) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci;
CREATE TABLE `imagebank_image` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(250) NOT NULL,
`img` varchar(250) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `imagebank_image2catalog` (
`image_id` int(11) NOT NULL,
`catalog_id` int(11) NOT NULL,
PRIMARY KEY (`image_id`,`catalog_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `imagebank_image2supplier` (
`image_id` int(11) NOT NULL,
`supplier_id` int(11) NOT NULL,
PRIMARY KEY (`image_id`,`supplier_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `imagebank_supplier` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(250) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `imagebank_supplier2catalog` (
`supplier_id` int(11) NOT NULL,
`catalog_id` int(11) NOT NULL,
PRIMARY KEY (`supplier_id`,`catalog_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `imagebank_supplier2user` (
`supplier_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
PRIMARY KEY (`supplier_id`,`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
SOME DATA:
INSERT INTO `imagebank` (`id`, `name`, `url`, `childof`, `hide`, `publishdate`, `expiredate`, `editdate`, `editbygroup`, `openby`, `opendate`) VALUES
(1, 'Test 1', 'test-1', '', 0, '20100204230233', '', '', '', '', ''),
(2, 'Test 2', 'test-2', '', 0, '20100204230244', '', '', '', '', '');
INSERT INTO `imagebank_image` (`id`, `name`, `img`) VALUES
(1, 'Test img 1', 'labb_9noq80bik5.jpeg'),
(2, 'Test img 2', 'labb_53626114dz.jpeg');
INSERT INTO `imagebank_image2catalog` (`image_id`, `catalog_id`) VALUES
(1, 1),
(2, 2);
INSERT INTO `imagebank_image2supplier` (`image_id`, `supplier_id`) VALUES
(1, 2),
(2, 1);
INSERT INTO `imagebank_supplier` (`id`, `name`) VALUES
(1, 'Supplier1'),
(2, 'Supplier2'),
(3, 'Supplier3');
INSERT INTO `imagebank_supplier2catalog` (`supplier_id`, `catalog_id`) VALUES
(1, 2),
(2, 1);
INSERT INTO `imagebank_supplier2user` (`supplier_id`, `user_id`) VALUES
(1, 1),
(1, 11),
(1, 12),
(2, 1),
(2, 10),
(3, 1);
INSERT INTO `user` (`id`, `email`, `password`) VALUES
(1, 'User1#test.com', 'ff02dd5s33taa2ba5ff7c2c4d3327e444'),
(10, 'User2#test.com', 'ff02dd5s33taa2ba5ff7c2c4d3327e444'),
(11, 'User3#test.com', 'ff02dd5s33taa2ba5ff7c2c4d3327e444'),
(12, 'User4#test.com', 'ff02dd5s33taa2ba5ff7c2c4d3327e444');
WOW, now thats alot of stuff :P So I know that the tables, specially for "catalogs" which i call just "imagebank" might look abit strange. But I do have my reasons and thats not really the issue :) Its part of an even bigger picture. Hope this helps you to help me. Thanks again.
It looks like if you are passing in the user and catalogue id's then the supplier doesn't matter.
If you required the supplier information in the result, that would be a different matter.
It feels like you shouldn't be involving the user in this query at all as you seem to be looking for the images in a catalogue that are owned by a particular supplier.
If that is the case, then I would drop the requirement for the user id in the query and use the supplier id instead.
I am assuming that the user would have done the following to get to the point where they would be initiating this query:
login - obviously :)
click on 'list suppliers'
click on a supplier
click on a catalog
Either way you are going to have to do a lot of INNER JOIN's. For instance the query to retrieve the list of suppliers for a given user would be something like
SELECT
s.supplier_id,
s.Supplier_name
FROM
supplier s
INNER JOIN
user u
INNER JOIN
user2supplier u2s
ON
u.user_id = u2s.user_id
ON
u2s.supplier_id = s.supplier_id
WHERE
u.user_id = 3 -- for example...
(now, I haven't tested the SQL, but I think that is right...)
Let me know if I'm on the right track - if I have helped, I'd be happy to help some more if I can

PHP MYSQL Insert/Update

I have a simple table as below.
CREATE TABLE `stats` (
`id` int(11) NOT NULL auto_increment,
`zones` varchar(100) default NULL,
`date` date default NULL,
`hits` int(100) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
So just storing simple hits counter per zone per day.
But I just want to increment the hits value for the same day.
I have tried the MYSQL DUPLICATE KEY UPDATE but this wont work as I may have many zones on different dates so I cant make them unique or dates.
So the only way I can think is first to do a query to see if a date exists then do a simple if() for insert/update
Is their a better way of doing such a task as there maybe be many 1000's hits per day.
Hope this makes sense :-).
And thanks if you can advise.
Declare the tuple (zone, date) as unique in your CREATE statement. This will make INSERT ... ON DUPLICATE UPDATE work as expected:
CREATE TABLE `stats` (
`id` int(11) NOT NULL auto_increment,
`zone` varchar(100) default NULL,
`date` date default NULL,
`hits` int(100) default NULL,
PRIMARY KEY (`id`),
UNIQUE (`zone`, `date`)
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
INSERT INTO stats (zone, date, hits) values ('zone1', 'date1', 1) ON DUPLICATE KEY UPDATE hits = hits + 1;
$result = mysql_query("SELECT id FROM stats WHERE zone=$zone AND date=$today LIMIT 1");
if(mysql_num_rows($result)) {
$id = mysql_result($result,0);
mysql_query("UPDATE stats SET hits=hits+1 WHERE id=$id");
} else {
mysql_query("INSERT INTO stats (zone, date, hits) VALUES ($zone, $today, 1)");
}
Something like that, if I've interpreted you correctly... that's completely untested. You can figure out what the variables are.

Categories