Ben Halkum
Ben Halkum

Reputation: 11

PayPal IPN listener does not work when adding trial period to a subscription

I have a subscription based streaming site in which I am trying to implement a trial period of 3 days prior to the user being charged the monthly fee.

THINGS TO KNOW

UNMODIFIED WORKING PAYMENT SCREEN CODE

   <!-- Buy button -->
    <form action="{{link}}" method="post" id="paypal-form-pay">
        <!-- Identify your business so that you can collect the payments -->
        <input type="hidden" name="business" value="{{account}}">
        <!-- Specify a subscriptions button. -->
        <input type="hidden" name="cmd" value="_xclick-subscriptions">
        <!-- Specify details about the subscription that buyers will purchase -->
        <input type="hidden" name="item_name" value="{{subscription.pack}}">
        <input type="hidden" name="item_number" value="{{id}}">
        
        <input type="hidden" name="currency_code" value="{{subscription.currency}}">
        <input type="hidden" name="a3" id="paypalAmt" value="{{subscription.price}}">
        <input type="hidden" name="subscription" id="paypalAmt" value="{{subscription.id}}">
        <input type="hidden" name="p3" id="paypalValid" value="1">
        <input type="hidden" name="t3" value="M">
        
<input type="hidden" name="src" value="100">
<input type="hidden" name="sra" value="5">
        <input type="hidden" name="cancel_return" value="{{ url('wep_subscription_cancel',{"id":subscription.id})}}">
        <input type="hidden" name="return" value="{{ url('wep_subscription_paypal_finish',{"id":subscription.id})}}">
        <input type="hidden" name="notify_url" value="{{ url('wep_subscription_notify')}}">
        <input class="buy-btn" style="display:none" type="submit" value="Buy Subscription">

    </form>

UNMODIFIED WORKING LISTENER CODE



            $paypalURL = "https://www.paypal.com/cgi-bin/webscr";
            $ch = curl_init($paypalURL);
            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_SSLVERSION, 6);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
            curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);

            // Set TCP timeout to 30 seconds
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close', 'User-Agent: company-name'));
            $res = curl_exec($ch);
                
            $tokens = explode("\r\n\r\n", trim($res));
            $res = trim(end($tokens));

            if (strcmp($res, "VERIFIED") == 0 || strcasecmp($res, "VERIFIED") == 0) {
                $txn_id = !empty($request->get('txn_id'))?$request->get('txn_id'):'';
                
                if(!empty($txn_id)){
                    $payment_status = !empty($request->get('payment_status'))?$request->get('payment_status'):'';
                    $currency_code = $request->get('mc_currency');
                    $payment_gross =  !empty($request->get('mc_gross'))?$request->get('mc_gross'):0;
                    $item_number = $request->get('item_number');

                    $subscription = $em->getRepository("AppBundle:Subscription")->findOneBy(array("id"=>$item_number,"method"=>"paypal","status"=>"unpaid"));

                    if (
                        $payment_status == "Completed" and 
                        $currency_code == $subscription->getCurrency() and
                        $payment_gross == $subscription->getPrice()
                    ) {
                        $subscr_id = $request->get('subscr_id');
                        $payer_email = $request->get('payer_email');
                        $payer_id = $request->get('payer_id');
                        $item_name = $request->get('item_name');
                        
                        $subscription->setEmail($payer_email);
                        $subscription->setStatus("paid");
                        $subscription->setTransaction($txn_id);

                        $started =  new \DateTime();
                        $expired =  new \DateTime();
                        $expired->modify('+'.$subscription->getDuration()." day");

                        $subscription->setStarted($started);
                        $subscription->setExpired($expired);

                        $em->flush();
                    }
                }

            }   
            return new Response("done"); 

    }
    public function finishAction(Request $request,$id){
        $em=$this->getDoctrine()->getManager();
        $subscription = $em->getRepository("AppBundle:Subscription")->findOneBy(array("user"=>$this->getUser(),"id"=>$id));
        if ($subscription == null) {
            throw new NotFoundHttpException("Page not found");  
        }
        return $this->render('WebBundle:Subscription:finish.html.twig',array("subscription"=>$subscription));
    }
    public function paypal_finishAction(Request $request,$id){
        $em=$this->getDoctrine()->getManager();
        $subscription = $em->getRepository("AppBundle:Subscription")->findOneBy(array("user"=>$this->getUser(),"id"=>$id));
        if ($subscription == null) {
            throw new NotFoundHttpException("Page not found");  
        }
        return $this->render('WebBundle:Subscription:paypal_finish.html.twig',array("subscription"=>$subscription));
    }

IPM RESPONSE FOR UNMODIFIED CODE THAT WORKS

mc_gross=0.01&protection_eligibility=Eligible&address_status=confirmed&payer_id=3H4HMXYSVLVWL&address_street=6384 flathead avenue&payment_date=11:26:19 Mar 29, 2021 PDT&payment_status=Completed&charset=windows-1252&address_zip=89122&first_name=Benjamin&mc_fee=0.01&address_country_code=US&address_name=Benjamin Halkum&notify_version=3.9&subscr_id=I-HY6W0PTGL3NB&payer_status=unverified&business=REMOVED.com&address_country=United States&address_city=Las Vegas&verify_sign=ArlJEh2PTclCmA4aNtb3eN2HF8lEAGBRRl4PvyzHc0gTKjP7ykq8080X&[email protected]&txn_id=4W280838190693944&payment_type=instant&last_name=Halkum&address_state=NV&[email protected]&payment_fee=0.01&receiver_id=NFGUHZAMQSLPS&txn_type=subscr_payment&item_name=Test Only&mc_currency=USD&item_number=314&residence_country=US&receipt_id=0577-5054-4256-1714&transaction_subject=Test Only&payment_gross=0.01&ipn_track_id=79a7131ef33e4

MODIFIED PAYMENT CODE WITH TRIAL

<!-- Buy button -->
    <form action="{{link}}" method="post" id="paypal-form-pay">
        <!-- Identify your business so that you can collect the payments -->
        <input type="hidden" name="business" value="{{account}}">
        <!-- Specify a subscriptions button. -->
        <input type="hidden" name="cmd" value="_xclick-subscriptions">
        <!-- Specify details about the subscription that buyers will purchase -->
        <input type="hidden" name="item_name" value="{{subscription.pack}}">
        <input type="hidden" name="item_number" value="{{id}}">
        
                <input type="hidden" name="currency_code" value="{{subscription.currency}}">
        <input type="hidden" name="a1" id="paypalAmt" value="0.00">
        <input type="hidden" name="subscription" id="paypalAmt" value="{{subscription.id}}">
        <input type="hidden" name="p1" id="paypalValid" value="1">
        <input type="hidden" name="t1" value="D">
        
        
        <input type="hidden" name="currency_code" value="{{subscription.currency}}">
        <input type="hidden" name="a3" id="paypalAmt" value="{{subscription.price}}">
        <input type="hidden" name="subscription" id="paypalAmt" value="{{subscription.id}}">
        <input type="hidden" name="p3" id="paypalValid" value="1">
        <input type="hidden" name="t3" value="M">
        
<input type="hidden" name="src" value="100">
<input type="hidden" name="sra" value="5">
        <input type="hidden" name="cancel_return" value="{{ url('wep_subscription_cancel',{"id":subscription.id})}}">
        <input type="hidden" name="return" value="{{ url('wep_subscription_paypal_finish',{"id":subscription.id})}}">
        <input type="hidden" name="notify_url" value="{{ url('wep_subscription_notify')}}">
        <input class="buy-btn" style="display:none" type="submit" value="Buy Subscription">

    </form>

MODIFIED CODE IPN RESPONSE MESSEGE

amount1=0.00&amount3=6.99&address_status=unconfirmed&subscr_date=11:39:54 Mar 29, 2021 PDT&payer_id=3H4HMXYSVLVWL&address_street=REMOVED&mc_amount1=0.00&mc_amount3=6.99&charset=windows-1252&address_zip=89122&first_name=Benjamin&reattempt=1&address_country_code=US&address_name=Benjamin Halkum&notify_version=3.9&subscr_id=I-G1VY47ASJ8C4&payer_status=unverified&business=REMOVED.com&address_country=United States&address_city=Las Vegas&verify_sign=AhM9chhyQTrOGTRyOPkwcY26Rcv3AhiXC3kA9XVfl3desynG0cKTMHw4&[email protected]&last_name=Halkum&address_state=NV&receiver_email=REMOVED.com&recurring=1&txn_type=subscr_signup&item_name=Monthly*&mc_currency=USD&item_number=318&residence_country=US&period1=1 D&period3=1 M&ipn_track_id=bfcdb7a2bc514

Upvotes: 0

Views: 105

Answers (1)

Preston PHX
Preston PHX

Reputation: 30369

The sample in your "MODIFIED CODE IPN RESPONSE MESSAGE" appears to be what is expected, so this is a matter of updating your listener to handle a different payload when there is a trial period. Among other things, there will be no transaction yet and hence no txn_id, so you will need to write code for the new situation.

Upvotes: 1

Related Questions