2012-04-24 21 views
5

मैं पेपैल से अनुकूली भुगतान प्रणाली का उपयोग कर रहा हूं। एक सैंडबॉक्स खाते का उपयोग करके, मैं पेरूक्वेट बनाने में सक्षम था और भुगतान करने के लिए पेपैल को भेज दिया गया था। यह तो है की तरह लग रही:आईपीएन के साथ पेपैल अनुकूली भुगतान का उपयोग कैसे करें?

अनुरोध =

अप्रैल 24, 2012 10:35:46 com.paypal.adaptive.api.requests.PayRequest निष्पादित जानकारी: requestEnvelope: साथ PayRequest भेजा जा रहा है। errorLanguage = hi & actionType = भुगतान & receiverList.receiver (0) .email = seller_1334320690_biz% 40email.org & receiverList.receiver (0) .amount = 5.0 & CurrencyCode = यूरो & feesPayer = प्रेषक & cancelUrl = https% 3A% 2F% 2Flocalhost% 3A8443 & returnUrl = http% 3A% 2F% 2Flocalhost% 2F & ipnNotificationUrl = http% 3A % 2F% 2Flocalhostu% 2Ffinishdeposit &

रिस्पांस =

24 April 2012 10:35:48 com.paypal.adaptive.api.requests.PayPalBaseRequest makeRequest जानकारी: प्राप्त प्रतिक्रिया: responseEnvelope.timestamp = 2012-04-24T13% 3A35% 3A48.587-07% 3A00 & responseEnvelope। ack = सफलता & responseEnvelope.correlationId = c8dee8023cca6 & responseEnvelope.build = 2,756,816 & payKey = एपी 1UF57245CJ360523K & paymentExecStatus = बनाया

मैं अब मैं कैसे जांच कर सकते हैं, यह पता लगाने की कोशिश कर रहा हूँ, टी वह भुगतान सफलतापूर्वक पूरा हो गया था। इसलिए मैंने आईपीएन सिस्टम को लागू करने की कोशिश की, जो सैंडबॉक्स टूल का उपयोग करके काम करता है। हालांकि, मुझे नहीं पता कि 2 को एक साथ कैसे कनेक्ट किया जाए। यानी जब भुगतान किया जाता है, तो मुझे लगता है कि मुझे डेटाबेस में एक रिकॉर्ड बनाने की आवश्यकता है जिसे इस उपयोगकर्ता ने भुगतान किया है, संभवतः लंबित/बनाया गया है? फिर आईपीएन को मुझे सूचित करने के लिए वापस आने के लिए प्रतीक्षा करें कि भुगतान किया गया है, और डेटाबेस तालिका को पूर्ण कहने के लिए अपडेट करें? मैं आईपीएन-अधिसूचना के लिए PayRequest से कैसे सहसंबंध कर सकता हूं, मुझे पेपैल से मिलेगा?

  • ITEM_NUMBER = एके-1234
  • residence_country = अमेरिका
  • verify_sign = ArcmaOINNZx08uC3iQY0zhEQN3IZAz70ynRk93Or8ixRi23bb4rGNIrd
  • address_country = यूनाइटेड स्टेट्स
  • address_city = सैन: Paypal केवल तरह IPN-सूचना के साथ कुछ जानकारी भेज रहा है जोस
  • पता_स्टैटस = असुविधाजनक
  • payment_status = पूर्ण
  • [email protected]
  • payer_id = TESTBUYERID01
  • first_name = जॉन
  • शिपिंग = 3.04
  • [email protected]
  • mc_fee = 0.44
  • txn_id = 484,221,854
  • मात्रा = 1
  • [email protected]
  • notify_version = 2.1
  • txn_type = web_accept
  • test_ipn = 1
  • payer_status = सत्यापित
  • mc_currency = अमरीकी डालर
  • mc_gross = 12.34
  • कस्टम = xyz123
  • mc_gross_1 = 9.34
  • PAYMENT_DATE = 11: 54: 48 अप्रैल 22, 2012 पीडीटी
  • charset = windows-1252
  • address_country_code = अमेरिका
  • address_zip = 95131
  • address_state = सीए
  • कर = कुछ 2.02
  • ITEM_NAME =
  • ADDRESS_NAME = जॉन स्मिथ
  • last_name = स्मिथ
  • payment_type = तत्काल
  • पता_स्ट्रीट = 123, कोई भी सड़क
  • receiver_i डी = TESTSELLERID1

मुझे उस आईपीएन-नोटिफिकेशन में कुछ उपयोग करने योग्य नहीं मिल रहा है। सबसे अच्छा होगा अगर मैं आईपीएन-अधिसूचना के साथ एक ही सहसंबंध-आईडी प्राप्त कर सकता हूं जो मुझे पहले से ही भुगतान-प्रतिक्रिया के साथ मिला है। इसलिए मैं अपने डेटाबेस पर प्रतिक्रिया-सहसंबंध-आईडी को सहेज सकता हूं और फिर यदि मैं उसी सहसंबंध-आईडी के साथ आईपीएन-अधिसूचना प्राप्त करता हूं तो इसके खिलाफ जांच कर सकता हूं।

+0

तो यह स्पष्ट करने के लिए कि आप भुगतान लेने के लिए अनुकूली भुगतान (पीएई) विधि का उपयोग करना चाहते हैं और फिर सफलता सत्यापित करने के लिए आईपीएन संदेश का उपयोग करना चाहते हैं? – swade1987

+0

हाँ और मैं भुगतान करने वाले उपयोगकर्ता को भुगतान को सहसंबंधित करना चाहता हूं। – lazydaemon

उत्तर

2

इससे आपको बड़े पैमाने पर मदद मिलनी चाहिए।

namespace Gateway 
{ 
    public class MerchantSellerIPNService : IMerchantSellerIPNService 
    { 
     /// <summary> 
     /// This is the method which is hit when using the URL in the PAY request to PayPal. 
     /// </summary> 
     /// <param name="stream"></param> 
     /// <returns></returns> 
     public string ProcessIPN(Stream stream) 
     { 
      // Declare locally used variables. 
      byte[] requestArray = null; 
      string requestString = null; 
      string responseString = null; 
      StreamReader IPNReturnReader; 
      StreamWriter streamWriter; 
      MemoryStream responseStream = new MemoryStream(); 
      HttpWebRequest payPalRequest; 
      System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); 

      // Get the URL to send the IPN received back to PayPal (use either of the two below depending on the environment.) 
      <add key="PAYPAL_IPN_URL" value="https://www.sandbox.paypal.com/cgi-bin/webscr" /> 
      <add key="PAYPAL_IPN_URL" value="https://www.paypal.com/cgi-bin/webscr"/> 

      string IPNReturnURL = ConfigurationManager.AppSettings["PAYPAL_IPN_URL"]; 

      // Read in the data provided from PayPal 
      StreamReader streamReader = new StreamReader(stream); 

      // Obtain the email address and pre-approval key passed to use via PayPal for later use. 
      string strPayPalMessage = streamReader.ReadToEnd(); 

      // Initalize the POST web request we are going to send to PayPal to valid the IPN we received from them. 
      payPalRequest = (HttpWebRequest)WebRequest.Create(IPNReturnURL); 
      payPalRequest.Method = "POST"; 
      payPalRequest.ContentType = "application/x-www-form-urlencoded"; 

      // Create an array containing the IPN message PayPal sent to us. 
      requestArray = encoding.GetBytes(strPayPalMessage); 

      // Then add the necessary string to the back to use for verfication. 
      requestString = Encoding.ASCII.GetString(requestArray); 
      requestString += "&cmd=_notify-validate"; 
      payPalRequest.ContentLength = requestString.Length; 

      // Now write the updated IPN message back to PayPal for verification. 
      streamWriter = new StreamWriter(payPalRequest.GetRequestStream(), System.Text.Encoding.ASCII); 
      streamWriter.Write(requestString); 
      streamWriter.Close(); 

      // Read the response from PayPal and process it. 
      IPNReturnReader = new StreamReader(payPalRequest.GetResponse().GetResponseStream()); 
      responseString = IPNReturnReader.ReadToEnd(); 
      IPNReturnReader.Close(); 

      if (responseString == "VERIFIED") 
      { 
       try 
       { 
        if (strPayPalMessage.Contains("payment_status=Completed")) 
        { 
         if (ProcessPaymentIPNMessage(strPayPalMessage)) 
          PayPalInStore.Utils.ErrorHandler.LogError(new Exception("ProcessPaymentIPNMessage - Able to create new payment Transaction Detail Record"), "DEBUG"); 
         else 
          PayPalInStore.Utils.ErrorHandler.LogError(new Exception("ProcessPaymentIPNMessage - Unable to create new payment Transaction Detail Record"), "DEBUG"); 
        } 
        else if (strPayPalMessage.Contains("payment_status=Refunded")) 
        { 
         if (ProcessRefundIPNMessage(strPayPalMessage)) 
          PayPalInStore.Utils.ErrorHandler.LogError(new Exception("ProcessRefundIPNMessage - Able to create new refund Transaction Detail Record"), "DEBUG"); 
         else 
          PayPalInStore.Utils.ErrorHandler.LogError(new Exception("ProcessRefundIPNMessage - Unable to create new refund Transaction Detail Record"), "DEBUG"); 
        } 
        else 
        { 
         PayPalInStore.Utils.ErrorHandler.LogError(new Exception("MerchantSellerIPNService - ProcessIPN - Unknown message type"), "DEBUG"); 
        } 
       } 
       catch (Exception ex) 
       { 
        PayPalInStore.Utils.ErrorHandler.LogError(new Exception("MerchantSellerIPNService - ProcessIPN failed"), "DEBUG"); 
       } 
      } 
      else if (responseString == "INVALID") 
      { 
       PayPalInStore.Utils.ErrorHandler.LogError(new Exception("MerchantSellerIPNService - Invalid IPN Message Received: "), "DEBUG"); 
      } 
      else 
      { 
       PayPalInStore.Utils.ErrorHandler.LogError(new Exception("MerchantSellerIPNService - Fatal IPN Message Received: "), "DEBUG"); 
      } 

      return "MerchantSellerIPNService Completed"; 
     } 

     /// <summary> 
     /// Method used to process the Payment IPN notification message and update the database as required. 
     /// </summary> 
     /// <returns></returns> 
     private bool ProcessPaymentIPNMessage(string PayPalIPNMessage) 
     { 
      // Firstly, we need to split the IPN message into sections based on the & sign. 
      string[] PayPalMessageElemetsArray = PayPalIPNMessage.Split('&'); 

      // Now obtain the list of information (from the message) we require to make the TransactionDetail record. 
      string merchantTransactionId = Array.Find(PayPalMessageElemetsArray, element => element.StartsWith("txn_id=", StringComparison.Ordinal)); 
      string feeAmount = Array.Find(PayPalMessageElemetsArray, element => element.StartsWith("mc_fee=", StringComparison.Ordinal)); 
      string grossAmount = Array.Find(PayPalMessageElemetsArray, element => element.StartsWith("mc_gross=", StringComparison.Ordinal)); 

      // TODO: REMOVE THIS ITS FOR DEBUGGING PURPOSES 
      string errorMessage2 = String.Format("ProcessPaymentIPNMessage - merchantTransactionId: {0}, feeAmount: {1}, grossAmount: {2}", merchantTransactionId, feeAmount, grossAmount); 
      PayPalInStore.Utils.ErrorHandler.LogError(new Exception(errorMessage2), "DEBUG"); 

      try 
      { 
       // We now need to remove the variable name and '=' from the elements so we only have the necessary information. 
       merchantTransactionId = merchantTransactionId.Replace("txn_id=", ""); 
       feeAmount = feeAmount.Replace("mc_fee=", ""); 
       grossAmount = grossAmount.Replace("mc_gross=", ""); 

       // Now convert the values obtained from the IPN message and calculate the net amount. 
       decimal dFeeAmount = Convert.ToDecimal(feeAmount); 
       decimal dGrossAmount = Convert.ToDecimal(grossAmount); 
       decimal dNetAmount = Math.Round((dGrossAmount - dFeeAmount), 2); 

       try 
       { 
        // Finally create the new transaction fee record. 
        TransactionDetail transactionDetail = new TransactionDetail(); 
        transactionDetail.MerchantTransactionId = merchantTransactionId; 
        transactionDetail.Gross = dGrossAmount; 
        transactionDetail.Fee = Decimal.Negate(dFeeAmount); 
        transactionDetail.Net = dNetAmount; 
        transactionDetail.TransactionType = (int)TransactionDetailTransactionType.InStorePayment; 
        transactionDetail.Save(); 
       } 
       catch (Exception ex) 
       { 
        string errorMessage = String.Format("ProcessPaymentIPNMessage - Unable to create new TransactionDetail record for Merchant Transaction ID: {0}", merchantTransactionId); 
        PayPalInStore.Utils.ErrorHandler.LogError(new Exception(errorMessage), "DEBUG"); 
        return false; 
       } 

       return true; 
      } 
      catch (Exception ex) 
      { 
       string errorMessage = String.Format("ProcessPaymentIPNMessage - Unable to create new TransactionDetail record for Merchant Transaction ID: {0}", merchantTransactionId); 
       PayPalInStore.Utils.ErrorHandler.LogError(new Exception(errorMessage), "DEBUG"); 
       return false; 
      } 
     } 

     /// <summary> 
     /// Method used to process the Refund IPN notification message and update the database as required. 
     /// </summary> 
     /// <returns></returns> 
     private bool ProcessRefundIPNMessage(string PayPalIPNMessage) 
     { 
      // Firstly, we need to split the IPN message into sections based on the & sign. 
      string[] PayPalMessageElemetsArray = PayPalIPNMessage.Split('&'); 

      // Now obtain the list of information (from the message) we require to make the TransactionDetail record. 
      string merchantTransactionId = Array.Find(PayPalMessageElemetsArray, element => element.StartsWith("txn_id=", StringComparison.Ordinal)); 
      string parentTransactionId = Array.Find(PayPalMessageElemetsArray, element => element.StartsWith("parent_txn_id=", StringComparison.Ordinal)); 
      string feeAmount = Array.Find(PayPalMessageElemetsArray, element => element.StartsWith("mc_fee=", StringComparison.Ordinal)); 
      string grossAmount = Array.Find(PayPalMessageElemetsArray, element => element.StartsWith("mc_gross=", StringComparison.Ordinal)); 

      try 
      { 
       // We now need to remove the variable name and '=' from the elements so we only have the necessary information. 
       merchantTransactionId = merchantTransactionId.Replace("txn_id=", ""); 
       parentTransactionId = parentTransactionId.Replace("parent_txn_id=", ""); 
       feeAmount = feeAmount.Replace("mc_fee=", "").Replace("-", ""); 
       grossAmount = grossAmount.Replace("mc_gross=", "").Replace("-", ""); 

       // Now convert the values obtained from the IPN message and calculate the net amount. 
       decimal dFeeAmount = Convert.ToDecimal(feeAmount); 
       decimal dGrossAmount = Convert.ToDecimal(grossAmount); 
       decimal dNetAmount = Math.Round((dGrossAmount - dFeeAmount), 2); 

       // Now create the new transaction fee record. 
       try 
       { 
        // Finally create the new transaction fee record. 
        TransactionDetail transactionDetail = new TransactionDetail(); 
        transactionDetail.MerchantTransactionId = merchantTransactionId; 
        transactionDetail.Gross = dGrossAmount; 
        transactionDetail.Fee = Decimal.Negate(dFeeAmount); 
        transactionDetail.Net = dNetAmount; 
        transactionDetail.TransactionType = (int)TransactionDetailTransactionType.InStoreRefund; 
        transactionDetail.Save(); 
       } 
       catch (Exception ex) 
       { 
        string errorMessage = String.Format("ProcessPaymentIPNMessage - Unable to create new TransactionDetail record for Merchant Transaction ID: {0}", merchantTransactionId); 
        PayPalInStore.Utils.ErrorHandler.LogError(new Exception(errorMessage), "DEBUG"); 
        return false; 
       } 

       // Finally update the PurchaseRefund record with the Parent Transaction Id (used as a backup incase the API IPN message for the payment wasn't received). 
       try 
       { 
        PurchaseRefund refund = PurchaseRefund.SingleOrDefault(x => x.RefundTransactionId == merchantTransactionId); 
        if (refund != null) 
        { 
         refund.ParentTransactionId = parentTransactionId; 
         refund.Save(); 
        } 
       } 
       catch (Exception ex) 
       { 
        string errorMessage = String.Format("ProcessPaymentIPNMessage - Unable to update PurchaseRefund record (Transaction ID: {0}) with Parent Transaction Id: {1}", merchantTransactionId, parentTransactionId); 
        PayPalInStore.Utils.ErrorHandler.LogError(new Exception(errorMessage), "DEBUG"); 
        return false; 
       } 

       // If all is succesful we can return true. 
       return true; 
      } 
      catch (Exception ex) 
      { 
       string errorMessage = String.Format("ProcessPaymentIPNMessage - Unable to create new TransactionDetail record for Merchant Transaction ID: {0}", merchantTransactionId); 
       PayPalInStore.Utils.ErrorHandler.LogError(new Exception(errorMessage), "DEBUG"); 
       return false; 
      } 
     } 
    } 
} 
13

परीक्षण आईपीएन वे आपको सैंडबॉक्स में देते हैं भयानक है।अपने वास्तविक कॉलबैक (यहां तक ​​कि एक परीक्षण) में ट्रिगर किए गए वास्तविक व्यक्ति को देखें, और आप देखेंगे कि इसका भुगतान पेकी परिभाषित है; यह आप इसे देखने के लिए उपयोग करते हैं।

ध्यान दें कि उन्हें आईपीएन कॉलबैक के लिए पोर्ट 80 की आवश्यकता है (हालांकि यह कहीं भी दस्तावेज नहीं है)।

{"payment_request_date":"Sun Jun 24 06:12:20 PDT 2012", 
"return_url":"http://redacted/paypal/transactions/3?status=completed", 
"fees_payer":"EACHRECEIVER", 
"ipn_notification_url":"http://redacted/paypal/notifications", 
"sender_email":"redacted", 
"verify_sign":"AFcWxVredacted", 
"test_ipn":"1", 
"transaction[0].id_for_sender_txn":"redacted", 
"transaction[0].receiver":"redacted", 
"cancel_url":"http://redacted/paypal/transactions/3?status=canceled", 
"transaction[0].is_primary_receiver":"false", 
"pay_key":"AP-redacted", 
"action_type":"PAY", 
"transaction[0].id":"redacted", 
"transaction[0].status":"Completed", 
"transaction[0].paymentType":"SERVICE", 
"transaction[0].status_for_sender_txn":"Completed", 
"transaction[0].pending_reason":"NONE", 
"transaction_type":"Adaptive Payment PAY", 
"transaction[0].amount":"USD 1.00", 
"status":"COMPLETED", 
"log_default_shipping_address_in_transaction":"false", 
"charset":"windows-1252", 
"notify_version":"UNVERSIONED", 
"reverse_all_parallel_payments_on_error":"true"} 

नोट आप मैन्युअल रूप से भुगतान अनुरोध में reverse_all_parallel_payments_on_error सेट करने के लिए है कि:

यहाँ एक वास्तविक IPN अधिसूचना (JSON में अनुवाद किया, जानकारी संशोधित मेरे ऐप पर विशेष) है। भले ही वे ऐसा करने की अनुशंसा करते हैं (और यह शायद आपको एंजस्ट बचाएगा) यह डिफ़ॉल्ट रूप से गलत है।

इसके अलावा, यदि आप आईपीएन याद करते हैं तो आप सभी समान जानकारी प्राप्त करने के लिए भुगतान विवरण का उपयोग कर सकते हैं।

मुझे पता नहीं था कि @ swade1987 क्या देख रहा था, लेकिन मेरे आईपीएन में शुल्क राशि के बारे में कोई जानकारी शामिल नहीं है। (। यही कारण है कि वास्तव में कैसे मैं इस पोस्ट पाया है,। यह पता लगाने की क्यों पीपी API दस्तावेज़ भयंकर है की कोशिश कर रहा)

अतिरिक्त दस्तावेज़ यहाँ https://developer.paypal.com/docs/classic/adaptive-payments/integration-guide/APIPN/

+8

दूसरा "डरावना" –

+2

खुशी है कि मुझे यह पोस्ट मिला। मैं भ्रमित हो रहा था क्यों सैंडबॉक्स आईपीएन अधिसूचना वास्तविक भुगतान से अलग थी। बहुत खुश है कि मैंने टेस्ट आईपीएन को संभालने के लिए टेबल और क्लास फाइलों का निर्माण करने में उम्र बिताई, जब असली कोई ऐसा नहीं है। धन्यवाद पेपैल आप शासन करते हैं! – sapatos

+1

ओपी की तरह, मैं इस धारणा पर परेशान था कि भुगतानकर्ता को मेरी लिपि में वापस नहीं भेजा जा रहा था। इसे साझा करने के लिए धन्यवाद! –

3

पाया जा सकता है थोड़ा देर से लेकिन जो कोई भी एक खोज से यहाँ में मुलाकात के लिए इंजन ...

मैंने अभी हाल ही में पेपैल एपीआई से निपटना शुरू कर दिया है। आईपीएन संदेश ओपी उद्धरण है जो विक्रेता प्रोफाइल में परिभाषित आईपीएन अधिसूचना यूआरएल पर दिया गया है। इसके विपरीत, @ एसई द्वारा उद्धृत आईपीएन, अनुकूली भुगतान आईपीएन है, जो पे, एक्ज़िक्यूटपेपमेंट या प्रीप्रोवल एपीआई अनुरोधों में परिभाषित आईपीएन नोटिफिकेशन यूआरएल को दिया जाता है।

वे दो अलग-अलग प्रकार के आईपीएन संदेश हैं और documented हैं, भुगतान सूचना चर और भुगतान/प्रीप्रोवल संदेश चर के लिए देखें। यदि आप दोनों के लिए चुनते हैं तो आप दोनों प्रकार के आईपीएन प्राप्त कर सकते हैं।

ओपी द्वारा उद्धृत आईपीएन संदेश के बारे में, आप लेनदेन द्वारा भुगतान विवरण प्राप्त करने के लिए txn_id फ़ील्ड के मान का उपयोग कर सकते हैं। ट्रांसलेशन आईडी एक पूर्ण भुगतान के संदर्भ में पेकी के रूप में उतना ही अच्छा है।

संबंधित मुद्दे