如何通过PHP自动获取PayPal支付成功信息并核查用户购买状态?
Hey there! Let's walk through how to handle your two PayPal requirements in PHP, since you're already using a hosted button and have return settings set up.
First off, relying solely on the return page (where PayPal sends users after payment) isn't 100% reliable—users might close the tab before it loads, or the request could fail. The PayPal IPN (Instant Payment Notification) is the robust way to get payment details automatically, as it sends a server-to-server notification regardless of what the user does.
Setting up IPN for your hosted button
- Log into your PayPal account, go to Profile > Website Payment Preferences (or the equivalent in the new dashboard).
- Enable IPN, and set your IPN listener URL (e.g.,
https://yourdomain.com/paypal-ipn.php).
PHP IPN Listener Example
Create a file paypal-ipn.php with this code to validate and process the notification:
<?php // PayPal IPN validation endpoint (use sandbox URL for testing) $paypalUrl = 'https://www.paypal.com/cgi-bin/webscr'; // For sandbox testing, use: 'https://www.sandbox.paypal.com/cgi-bin/webscr' // Read POST data $rawPostData = file_get_contents('php://input'); $rawPostArray = explode('&', $rawPostData); $myPost = []; foreach ($rawPostArray as $keyval) { $keyval = explode('=', $keyval); if (count($keyval) == 2) { $myPost[$keyval[0]] = urldecode($keyval[1]); } } // Prepare request to PayPal $req = 'cmd=_notify-validate'; foreach ($myPost as $key => $value) { $value = urlencode(stripslashes($value)); $req .= "&$key=$value"; } // Send request to PayPal $ch = curl_init($paypalUrl); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $req); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($ch, CURLOPT_FORBID_REUSE, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Connection: Close']); $res = curl_exec($ch); curl_close($ch); // Process validated response if (strcmp($res, "VERIFIED") == 0) { // Payment is valid—extract details $paymentStatus = $_POST['payment_status']; $transactionId = $_POST['txn_id']; $payerEmail = $_POST['payer_email']; $amount = $_POST['mc_gross']; $itemName = $_POST['item_name']; // Do something with this data: save to database, send confirmation email, etc. // Example: Insert into a payments table (use prepared statements for security!) // $stmt = $pdo->prepare("INSERT INTO payments (txn_id, payer_email, amount, item_name, status) VALUES (?, ?, ?, ?, ?)"); // $stmt->execute([$transactionId, $payerEmail, $amount, $itemName, $paymentStatus]); } elseif (strcmp($res, "INVALID") == 0) { // Invalid payment—log this for investigation error_log("Invalid PayPal IPN: " . print_r($_POST, true)); } ?>
Bonus: Getting data from the return page
If you still want to handle the return page, PayPal will send GET/POST parameters to your configured return URL. You can access them like:
// On your return page (e.g., thank-you.php) if (isset($_GET['tx'])) { $transactionId = $_GET['tx']; $paymentStatus = $_GET['st']; $amount = $_GET['amt']; // Important: Always verify this data via PayPal (e.g., using the IPN or API) before trusting it }
To check if a user has purchased your product, you need to store payment records securely, then query that data when needed.
Step 1: Store payment records
When the IPN is verified (in the paypal-ipn.php code above), save key details to a database table. Here's a sample table schema:
CREATE TABLE payments ( id INT AUTO_INCREMENT PRIMARY KEY, txn_id VARCHAR(255) UNIQUE NOT NULL, payer_email VARCHAR(255) NOT NULL, item_name VARCHAR(255) NOT NULL, amount DECIMAL(10,2) NOT NULL, payment_status VARCHAR(50) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
Step 2: Check purchase status
Create a function to check if a user has a valid, completed payment for your product. For example, if you identify users by their email:
function hasPurchasedProduct($pdo, $userEmail, $productName) { $stmt = $pdo->prepare("SELECT COUNT(*) FROM payments WHERE payer_email = ? AND item_name = ? AND payment_status = 'Completed'"); $stmt->execute([$userEmail, $productName]); return $stmt->fetchColumn() > 0; } // Usage example: // $hasPurchased = hasPurchasedProduct($yourPdoInstance, 'user@example.com', 'Your Product Name'); // if ($hasPurchased) { // // Grant access to the product content // } else { // // Show purchase prompt or restrict access // }
Optional: Verify via PayPal API
If you want to double-check against PayPal's official records (e.g., as a fallback if your database is corrupted), you can use the PayPal Transaction Search API. You'll need to set up a PayPal REST API app, then use the SDK or direct API calls to fetch transaction details for a user's email. However, this is less efficient than using your own database, so it's best as a secondary check.
Important Notes
- Test with Sandbox: Always use PayPal's Sandbox environment to test IPN flows and payments before going live.
- Security: Sanitize all database inputs (use prepared statements like the examples above) to prevent SQL injection.
- Logging: Log IPN requests and responses to debug issues if payments aren't being processed correctly.
内容的提问来源于stack exchange,提问作者RGS

