问题
I integrating PayPal in Codeigniter 4 but I can't get data after the transaction for an updated database
What I want to do is to get a PayPal response from the IPN listener so that I can modify my database accordingly, but no matter what I do, it just won't work. I have already done the following in my PayPal Sandbox account:
- Enabled Auto Return
- Set Auto Return URL ('dashboard')
- Enabled Payment Data Transfer (PDT)
- Enabled IPN message reception
- Set IPN URL ('http:myDomain/Controller/index') The redirect to Auto Return URL not working fine too, after the transaction, the user can't back to the store until clicking the return button.
enter code here
I can't get data in the database, I am sending data
function index()
{
$raw_post_data = file_get_contents('php://input');
$raw_post_array = explode('&', $raw_post_data);
$myPost = array();
foreach ($raw_post_array as $keyval) {
$keyval = explode('=', $keyval);
if (count($keyval) == 2)
$myPost[$keyval[0]] = urldecode($keyval[1]);
}
$req = 'cmd=_notify-validate';
if (function_exists('get_magic_quotes_gpc')) {
$get_magic_quotes_exists = true;
}
foreach ($myPost as $key => $value) {
if ($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) {
$value = urlencode(stripslashes($value));
} else {
$value = urlencode($value);
}
$req .= "&$key=$value";
}
if (sandbox == true) {
$paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
} else {
$paypal_url = "https://www.paypal.com/cgi-bin/webscr";
}
$ch = curl_init($paypal_url);
if ($ch == FALSE) {
return FALSE;
}
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);
if (DEBUG == true) {
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
}
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
$res = curl_exec($ch);
if (curl_errno($ch) != 0) // cURL error
{
if (DEBUG == true) {
error_log(date('[Y-m-d H:i e] ') . "Can't connect to PayPal to validate IPN message: " . curl_error($ch) . PHP_EOL, 3, LOG_FILE);
}
curl_close($ch);
exit;
} else {
// Log the entire HTTP response if debug is switched on.
if (DEBUG == true) {
error_log(date('[Y-m-d H:i e] ') . "HTTP request of validation request:" . curl_getinfo($ch, CURLINFO_HEADER_OUT) . " for IPN payload: $req" . PHP_EOL, 3, LOG_FILE);
error_log(date('[Y-m-d H:i e] ') . "HTTP response of validation request: $res" . PHP_EOL, 3, LOG_FILE);
}
curl_close($ch);
}
// Inspect IPN validation result and act accordingly
// Split response headers and payload, a better way for strcmp
$tokens = explode("\r\n\r\n", trim($res));
$res = trim(end($tokens));
if (strcmp($res, "VERIFIED") == 0) {
// assign posted variables to local variables
$paypalInfo = $this->input->post();
$aData = array();
$item_name = $_POST['item_name'];
$data['product_id'] = $paypalInfo["item_number"];
$data['txn_id'] = $paypalInfo["txn_id"];
$data['payment_gross'] = $paypalInfo["mc_gross"];
$data['currency_code'] = $paypalInfo["mc_currency"];
$data['payer_email'] = $paypalInfo["payer_email"];
$data['payment_status'] = $paypalInfo["payment_status"];
// check whether the payment_status is Completed
$isPaymentCompleted = false;
if ($paypalInfo["payment_status"] == "Completed") {
$isPaymentCompleted = true;
}
if ($isPaymentCompleted) {
$oPaypalBuilder = $this->modelHelper->getBuilder('Paypal');
$oPaypalBuilder->skipValidation();
$oPaypalBuilder->insert($data);
}
// process payment and mark item as paid.
if (DEBUG == true) {
error_log(date('[Y-m-d H:i e] ') . "Verified IPN: $req " . PHP_EOL, 3, LOG_FILE);
}
} else if (strcmp($res, "INVALID") == 0) {
// log for manual investigation
// Add business logic here which deals with invalid IPN messages
if (DEBUG == true) {
error_log(date('[Y-m-d H:i e] ') . "Invalid IPN: $req" . PHP_EOL, 3, LOG_FILE);
}
}
}
I can't get data in the database, I am sending data
<form action="https://www.sandbox.paypal.com/cgi-bin/webscr"
method="post" class="d-none" id="paypal" target="_top">
<input type='hidden' name='business'
value=''> <input type='hidden'
name='item_name' value=''> <input type='hidden'
name='item_number' value=''> <input type='hidden'
name='amount' value=''> <input type='hidden'
name='no_shipping' value=''> <input type='hidden'
name='currency_code' value=''> <input type='hidden'
name='notify_url'
value=''>
<input type='hidden' name='cancel_return'
value=''>
<input type='hidden' name='return'
value=''>
<input type="hidden" name="cmd" value="_xclick">
</form>
回答1:
The redirect to Auto Return URL not working fine too, after the transaction, the user can't back to the store until clicking the return button.
This will always be an issue with the HTML-only (no API) integration you are using, the return is never guaranteed to happen. PayPal may be legally obligated to show the payer a receipt, and so they may not click to return, or their browser might simply crash before they return.
To ensure that a return happens and that your server is notified of completed transactions, you should switch to a proper API-based server-side integration.
Set up two routes on your server, one for 'Create an Order' and one for 'Capture Order', documented here: https://developer.paypal.com/docs/business/checkout/server-side-api-calls/ . On success, the Capture Order route should update your database.
The best approval flow to pair with your two routes is: https://developer.paypal.com/demo/checkout/#/pattern/server
来源:https://stackoverflow.com/questions/65271115/cant-update-database-after-paypal-transaction-in-codeigniter-4