duandianwen1723 2015-10-23 16:48
浏览 79
已采纳

Paypal IPN取消会员资格PHP

So the code that I've got for when a user purchases membership works perfectly. However I'm unsure how to code if for when the user cancels. What fields do papal throw at you when the user cancels through them?

I understand I'm supposed to use subscr_cancelled but am unsure the correct psuedocode and logic behind the cancellation.

For example:

  • What is the payment status when the user cancels?
  • Do I just ignore payment status?

Here's my code thus far, its a little clunky as i've been testing a lot:

if (strcmp ($res, "VERIFIED") == 0) {
    // check whether the payment_status is Completed
    // check that txn_id has not been previously processed
    // check that receiver_email is your PayPal email
    // check that payment_amount/payment_currency are correct
    // process payment and mark item as paid.
    // assign posted variables to local variables

    $item_name = $_POST['item_name'];
    $item_number = $_POST['item_number'];
    $txn_type = $_POST['txn_type'];
    $payment_status = $_POST['payment_status'];
    $payment_amount = $_POST['mc_gross'];
    $payment_currency = $_POST['mc_currency'];
    $txn_id = $_POST['txn_id'];
    $receiver_email = $_POST['receiver_email'];
    $payer_email = $_POST['payer_email'];
    $id = $_POST['custom'];
    $make_premium =1;
    $make_loser=0;


        if($payment_status=="Completed"){
        $user_id_check = $mysqli->query("SELECT `username` FROM `users` WHERE `ID` ='$id'");
        if($user_id_check->num_rows > 0){
            $txn_id_check = $mysqli->query("SELECT `transaction_id` FROM `payment` WHERE `transaction_id`='$txn_id'");
            if($txn_id_check->num_rows != 1) {  
                        $query = "INSERT INTO `payment` (`transaction_id`, `payment_status`, `users_id`, `txn_type`) VALUES(?, ?, ?, ?)";
                        $statement = $mysqli->prepare($query);
                        $statement->bind_param('ssis',$txn_id, $payment_status, $id, $txn_type);
                        if($statement->execute()){
                            if($txn_type =="subscr_signup"){
                                $update_user_to_premium =("UPDATE `users` SET `is_member` =? WHERE `ID` =?");
                                $stmt =$mysqli->prepare($update_user_to_premium);
                                $stmt->bind_param('ii',$make_premium,$id);
                                $stmt->execute();
                            }
                        }else{
                        die('Error : ('. $mysqli->errno .') '. $mysqli->error);
                        }
                        $statement->close();
               }
            }
        }
    }
    if($txn_id_check->num_rows == 1){
        if($txn_type=="subscr_cancel"){
            $update_user_to_loser =("UPDATE `users` SET `is_member` =? WHERE `ID` =?");
            $stmt =$mysqli->prepare($update_user_to_loser);
            $stmt->bind_param('ii',$make_loser,$id);
            $stmt->execute();
        }
    {
    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);
    }
}

Should I be using something like this

switch ($_POST['txn_type']) {   
 case 'subscr_signup':
        break;

    case 'subscr_eot':
       //subscription end of term
        break;

    case 'subscr_cancel':
        //subscription canceled
        break;

EDIT:

if (strcmp ($res, "VERIFIED") == 0) {
    // check whether the payment_status is Completed
    // check that txn_id has not been previously processed
    // check that receiver_email is your PayPal email
    // check that payment_amount/payment_currency are correct
    // process payment and mark item as paid.
    // assign posted variables to local variables

    $item_name = $_POST['item_name'];
    $item_number = $_POST['item_number'];
    $txn_type = $_POST['txn_type'];
    $payment_status = $_POST['payment_status'];
    $payment_amount = $_POST['mc_gross'];
    $payment_currency = $_POST['mc_currency'];
    $txn_id = $_POST['txn_id'];
    $receiver_email = $_POST['receiver_email'];
    $payer_email = $_POST['payer_email'];
    $id = $_POST['custom'];
    $subscr_id = $_POST['subscr_id'];
    $make_premium =1;
    $make_loser=0;


        if($payment_status=="Completed"){
        $user_id_check = $mysqli->query("SELECT `username` FROM `users` WHERE `ID` ='$id'");
        if($user_id_check->num_rows > 0){
            $txn_id_check = $mysqli->query("SELECT `transaction_id` FROM `payment` WHERE `transaction_id`='$txn_id'");
            if($txn_id_check->num_rows != 1) {  
                        $query = "INSERT INTO `payment` (`transaction_id`, `payment_status`, `users_id`, `txn_type`, `subscr_id`) VALUES(?, ?, ?, ?, ?)";
                        $statement = $mysqli->prepare($query);
                        $statement->bind_param('ssiss',$txn_id, $payment_status, $id, $txn_type, $subscr_id);
                        if($statement->execute()){
                            if($txn_type =="subscr_signup"){
                                $update_user_to_premium =("UPDATE `users` SET `is_member` =? WHERE `ID` =?");
                                $stmt =$mysqli->prepare($update_user_to_premium);
                                $stmt->bind_param('ii',$make_premium,$id);
                                $stmt->execute();
                            }
                        }else{
                        die('Error : ('. $mysqli->errno .') '. $mysqli->error);
                        }
                        $statement->close();
               }
            }
        }
    }

        if($txn_type=="subscr_cancel"){
            // get user id from row with subscription id 
            $get_user_id = $mysqli->("SELECT `users_id` FROM `payment` WHERE `subscr_id`='$subscr_id'");
            $row = $get_user_id->fetch_assoc();
            $users_id = $row[`users_id`];
            $update_user_to_loser =("UPDATE `users` SET `is_member` =? WHERE `ID` =?");
            $stmt =$mysqli->prepare($update_user_to_loser);
            $stmt->bind_param('ii',$make_loser,$users_id);
            $stmt->execute();
        }
    {
    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);
    }
}
?>
  • 写回答

1条回答 默认 最新

  • duanjieyi6582 2015-10-23 19:10
    关注

    If a profile is canceled then there is no payment taking place. That's a different type of transaction. There is no payment, so there is no payment status, so you won't get that parameter in that sort of an IPN.

    You can easily test this in the sandbox. You just need to create a seller account and a buyer account, and configure IPN in your seller account to hit your listener. Then create a subscription button from the seller account, sign up from the buyer account, and then cancel it. That will trigger IPNs for each step so you can see what to expect and adjust your IPN listener accordingly.

    Here is an example of an IPN for a subscr_cancel transaction.

    Array
    (
        [amount3] => 4.99
        [address_status] => confirmed
        [recur_times] => 2
        [subscr_date] => 15:51:33 Jan 19, 2015 PST
        [payer_id] => YW66KXBKJRRES
        [address_street] => 123 Test Ave
        [mc_amount3] => 4.99
        [charset] => windows-1252
        [address_zip] => 64030
        [first_name] => Tester
        [reattempt] => 1
        [address_country_code] => US
        [address_name] => Testers, LLC
        [notify_version] => 3.8
        [subscr_id] => S-6YS75493RP123324L
        [payer_status] => verified
        [business] => sandbo_1215254764_biz@angelleye.com
        [address_country] => United States
        [address_city] => Grandview
        [verify_sign] => AI7Wj0s667jdpY.UclGpjUpSpsZNAJzn.UcYbCVhXVG5fO05tyBo36EL
        [payer_email] => drew@angelleye.com
        [payer_business_name] => Testers, LLC
        [last_name] => Testerson
        [address_state] => MO
        [receiver_email] => sandbo_1215254764_biz@angelleye.com
        [recurring] => 1
        [txn_type] => subscr_cancel
        [item_name] => Test Subscription
        [mc_currency] => USD
        [item_number] => TEST-123
        [residence_country] => US
        [test_ipn] => 1
        [period3] => 1 M
        [ipn_track_id] => f0f2f2be88fd
    )
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改