Example #1
0
def make_secret(form_instance, secret_fields=None):
    """
    Returns a secret for use in a EWP form or an IPN verification based on a
    selection of variables in params. Should only be used with SSL.

    """
    warn_untested()
    # @@@ Moved here as temporary fix to avoid dependancy on auth.models.
    # @@@ amount is mc_gross on the IPN - where should mapping logic go?
    # @@@ amount / mc_gross is not nessecarily returned as it was sent - how to use it? 10.00 vs. 10.0
    # @@@ the secret should be based on the invoice or custom fields as well - otherwise its always the same.

    # Build the secret with fields availible in both PaymentForm and the IPN. Order matters.
    if secret_fields is None:
        secret_fields = ['business', 'item_name']

    data = ""
    for name in secret_fields:
        if hasattr(form_instance, 'cleaned_data'):
            if name in form_instance.cleaned_data:
                data += six.text_type(form_instance.cleaned_data[name])
        else:
            # Initial data passed into the constructor overrides defaults.
            if name in form_instance.initial:
                data += six.text_type(form_instance.initial[name])
            elif name in form_instance.fields and form_instance.fields[name].initial is not None:
                data += six.text_type(form_instance.fields[name].initial)

    secret = get_sha1_hexdigest(settings.SECRET_KEY, data)
    return secret
    def _verify_postback(self):
        # ### Now we don't really care what result was, just whether a flag was set or not.
        from paypal.standard.pdt.forms import PayPalPDTForm

        response_list = self.response.split('\n')
        response_dict = {}
        for i, line in enumerate(response_list):
            unquoted_line = unquote_plus(line).strip()
            if i == 0:
                self.st = unquoted_line
            else:
                if self.st != "SUCCESS":
                    warn_untested()
                    self.set_flag(line)
                    break
                try:
                    if not unquoted_line.startswith(' -'):
                        k, v = unquoted_line.split('=')
                        response_dict[k.strip()] = v.strip()
                except ValueError:
                    pass

        qd = QueryDict('', mutable=True)
        qd.update(response_dict)
        qd.update(
            dict(ipaddress=self.ipaddress,
                 st=self.st,
                 flag_info=self.flag_info,
                 flag=self.flag,
                 flag_code=self.flag_code))
        pdt_form = PayPalPDTForm(qd, instance=self)
        pdt_form.save(commit=False)
Example #3
0
    def _verify_postback(self):
        # ### Now we don't really care what result was, just whether a flag was set or not.
        from paypal.standard.pdt.forms import PayPalPDTForm

        response_list = self.response.split('\n')
        response_dict = {}
        for i, line in enumerate(response_list):
            unquoted_line = unquote_plus(line).strip()
            if i == 0:
                self.st = unquoted_line
            else:
                if self.st != "SUCCESS":
                    warn_untested()
                    self.set_flag(line)
                    break
                try:
                    if not unquoted_line.startswith(' -'):
                        k, v = unquoted_line.split('=')
                        response_dict[k.strip()] = v.strip()
                except ValueError:
                    pass

        qd = QueryDict('', mutable=True)
        qd.update(response_dict)
        qd.update(dict(ipaddress=self.ipaddress, st=self.st, flag_info=self.flag_info, flag=self.flag,
                       flag_code=self.flag_code))
        pdt_form = PayPalPDTForm(qd, instance=self)
        pdt_form.save(commit=False)
Example #4
0
 def set_flag(self, info, code=None):
     """Sets a flag on the transaction and also sets a reason."""
     self.flag = True
     self.flag_info += info
     if code is not None:
         warn_untested()
         self.flag_code = code
Example #5
0
    def init(self, request, paypal_request, paypal_response):
        """Initialize a PayPalNVP instance from a HttpRequest."""
        if request is not None:
            from paypal.pro.helpers import strip_ip_port
            self.ipaddress = strip_ip_port(request.META.get('REMOTE_ADDR', ''))
            if hasattr(request, "user") and request.user.is_authenticated():
                self.user = request.user
        else:
            self.ipaddress = ''

        # No storing credit card info.
        query_data = dict((k, v) for k, v in paypal_request.items()
                          if k not in self.RESTRICTED_FIELDS)
        self.query = urlencode(query_data)
        self.response = urlencode(paypal_response)

        # Was there a flag on the play?
        ack = paypal_response.get('ack', False)
        if ack != "Success":
            if ack == "SuccessWithWarning":
                warn_untested()
                self.flag_info = paypal_response.get('l_longmessage0', '')
            else:
                self.set_flag(paypal_response.get('l_longmessage0', ''),
                              paypal_response.get('l_errorcode', ''))
Example #6
0
 def clean(self, value):
     warn_untested()
     exp = super(CreditCardExpiryField, self).clean(value)
     if date.today() > exp:
         raise forms.ValidationError(
             "The expiration date you entered is in the past.")
     return exp
Example #7
0
 def set_flag(self, info, code=None):
     """Sets a flag on the transaction and also sets a reason."""
     self.flag = True
     self.flag_info += info
     if code is not None:
         warn_untested()
         self.flag_code = code
Example #8
0
def make_secret(form_instance, secret_fields=None):
    """
    Returns a secret for use in a EWP form or an IPN verification based on a
    selection of variables in params. Should only be used with SSL.

    """
    warn_untested()
    # @@@ Moved here as temporary fix to avoid dependancy on auth.models.
    # @@@ amount is mc_gross on the IPN - where should mapping logic go?
    # @@@ amount / mc_gross is not nessecarily returned as it was sent - how to use it? 10.00 vs. 10.0
    # @@@ the secret should be based on the invoice or custom fields as well - otherwise its always the same.

    # Build the secret with fields availible in both PaymentForm and the IPN. Order matters.
    if secret_fields is None:
        secret_fields = ['business', 'item_name']

    data = ""
    for name in secret_fields:
        if hasattr(form_instance, 'cleaned_data'):
            if name in form_instance.cleaned_data:
                data += unicode(form_instance.cleaned_data[name])
        else:
            # Initial data passed into the constructor overrides defaults.
            if name in form_instance.initial:
                data += unicode(form_instance.initial[name])
            elif name in form_instance.fields and form_instance.fields[name].initial is not None:
                data += unicode(form_instance.fields[name].initial)

    secret = get_sha1_hexdigest(settings.SECRET_KEY, data)
    return secret
Example #9
0
 def response_dict(self):
     """
     Returns a (MultiValueDict) dictionary containing all the parameters returned in the PayPal response.
     """
     # Undo the urlencode done in init
     warn_untested()
     return QueryDict(self.response)
Example #10
0
    def _encrypt(self):
        """Use your key thing to encrypt things."""
        warn_untested()
        from M2Crypto import BIO, SMIME, X509

        # Iterate through the fields and pull out the ones that have a value.
        plaintext = 'cert_id=%s\n' % self.cert_id
        for name, field in self.fields.items():
            value = None
            if name in self.initial:
                value = self.initial[name]
            elif field.initial is not None:
                value = field.initial
            if value is not None:
                plaintext += u'%s=%s\n' % (name, value)
        plaintext = plaintext.encode('utf-8')

        # Begin crypto weirdness.
        s = SMIME.SMIME()
        s.load_key_bio(BIO.openfile(self.private_cert), BIO.openfile(self.public_cert))
        p7 = s.sign(BIO.MemoryBuffer(plaintext), flags=SMIME.PKCS7_BINARY)
        x509 = X509.load_cert_bio(BIO.openfile(self.paypal_cert))
        sk = X509.X509_Stack()
        sk.push(x509)
        s.set_x509_stack(sk)
        s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
        tmp = BIO.MemoryBuffer()
        p7.write_der(tmp)
        p7 = s.encrypt(tmp, flags=SMIME.PKCS7_BINARY)
        out = BIO.MemoryBuffer()
        p7.write(out)
        return out.read()
Example #11
0
 def __init__(self, private_cert=PAYPAL_PRIVATE_CERT, public_cert=PAYPAL_PUBLIC_CERT,
         paypal_cert=PAYPAL_CERT, cert_id=PAYPAL_CERT_ID, *args, **kwargs):
     warn_untested()
     super(PayPalEncryptedPaymentsForm, self).__init__(*args, **kwargs)
     self.private_cert = private_cert
     self.public_cert = public_cert
     self.paypal_cert = paypal_cert
     self.cert_id = cert_id
Example #12
0
 def render_confirm_form(self):
     """
     Second step of ExpressCheckout. Display an order confirmation form which
     contains hidden fields with the token / PayerID from PayPal.
     """
     warn_untested()
     initial = dict(token=self.request.GET['token'], PayerID=self.request.GET['PayerID'])
     self.context[self.form_context_name] = self.confirm_form_cls(initial=initial)
     return TemplateResponse(self.request, self.confirm_template, self.context)
Example #13
0
def check_secret(form_instance, secret):
    """
    Returns true if received `secret` matches expected secret for form_instance.
    Used to verify IPN.

    """
    warn_untested()
    # @@@ add invoice & custom
    # secret_fields = ['business', 'item_name']
    return make_secret(form_instance) == secret
Example #14
0
def check_secret(form_instance, secret):
    """
    Returns true if received `secret` matches expected secret for form_instance.
    Used to verify IPN.

    """
    warn_untested()
    # @@@ add invoice & custom
    # secret_fields = ['business', 'item_name']
    return make_secret(form_instance) == secret
Example #15
0
    def _postback(self):
        """
        Perform PayPal PDT Postback validation.
        Sends the transaction ID and business token to PayPal which responses with
        SUCCESS or FAILED.

        """
        warn_untested()
        return requests.post(self.get_endpoint(),
                             data=dict(cmd="_notify-synch",
                                       at=IDENTITY_TOKEN,
                                       tx=self.tx)).content
Example #16
0
 def render_confirm_form(self):
     """
     Second step of ExpressCheckout. Display an order confirmation form which
     contains hidden fields with the token / PayerID from PayPal.
     """
     warn_untested()
     initial = dict(token=self.request.GET['token'],
                    PayerID=self.request.GET['PayerID'])
     self.context[self.form_context_name] = self.confirm_form_cls(
         initial=initial)
     return TemplateResponse(self.request, self.confirm_template,
                             self.context)
Example #17
0
    def __init__(self, *args, **kwargs):
        "Make the secret from the form initial data and slip it into the form."
        warn_untested()
        from paypal.standard.helpers import make_secret

        super(PayPalSharedSecretEncryptedPaymentsForm, self).__init__(*args, **kwargs)
        # @@@ Attach the secret parameter in a way that is safe for other query params.
        secret_param = "?secret=%s" % make_secret(self)
        # Initial data used in form construction overrides defaults
        if 'notify_url' in self.initial:
            self.initial['notify_url'] += secret_param
        else:
            self.fields['notify_url'].initial += secret_param
Example #18
0
    def __init__(self, *args, **kwargs):
        "Make the secret from the form initial data and slip it into the form."
        warn_untested()
        from paypal.standard.helpers import make_secret

        super(PayPalSharedSecretEncryptedPaymentsForm, self).__init__(*args, **kwargs)
        # @@@ Attach the secret parameter in a way that is safe for other query params.
        secret_param = "?secret=%s" % make_secret(self)
        # Initial data used in form construction overrides defaults
        if 'notify_url' in self.initial:
            self.initial['notify_url'] += secret_param
        else:
            self.fields['notify_url'].initial += secret_param
Example #19
0
 def redirect_to_express(self):
     """
     First step of ExpressCheckout. Redirect the request to PayPal using the
     data returned from setExpressCheckout.
     """
     wpp = PayPalWPP(self.request)
     try:
         nvp_obj = wpp.setExpressCheckout(self.item)
     except PayPalFailure:
         warn_untested()
         self.context['errors'] = self.errors['paypal']
         return self.render_payment_form()
     else:
         return HttpResponseRedirect(express_endpoint_for_token(nvp_obj.token))
Example #20
0
    def validate_payment_form(self):
        """Try to validate and then process the DirectPayment form."""
        warn_untested()
        form = self.payment_form_cls(self.request.POST)
        if form.is_valid():
            success = form.process(self.request, self.item)
            if success:
                return HttpResponseRedirect(self.success_url)
            else:
                self.context['errors'] = self.errors['processing']

        self.context[self.form_context_name] = form
        self.context.setdefault("errors", self.errors['form'])
        return TemplateResponse(self.request, self.payment_template, self.context)
Example #21
0
 def redirect_to_express(self):
     """
     First step of ExpressCheckout. Redirect the request to PayPal using the
     data returned from setExpressCheckout.
     """
     wpp = PayPalWPP(self.request)
     try:
         nvp_obj = wpp.setExpressCheckout(self.item)
     except PayPalFailure:
         warn_untested()
         self.context['errors'] = self.errors['paypal']
         return self.render_payment_form()
     else:
         return HttpResponseRedirect(
             express_endpoint_for_token(nvp_obj.token))
Example #22
0
    def validate_payment_form(self):
        """Try to validate and then process the DirectPayment form."""
        warn_untested()
        form = self.payment_form_cls(self.request.POST)
        if form.is_valid():
            success = form.process(self.request, self.item)
            if success:
                return HttpResponseRedirect(self.success_url)
            else:
                self.context['errors'] = self.errors['processing']

        self.context[self.form_context_name] = form
        self.context.setdefault("errors", self.errors['form'])
        return TemplateResponse(self.request, self.payment_template,
                                self.context)
Example #23
0
 def compress(self, data_list):
     warn_untested()
     if data_list:
         if data_list[1] in forms.fields.EMPTY_VALUES:
             error = self.error_messages['invalid_year']
             raise forms.ValidationError(error)
         if data_list[0] in forms.fields.EMPTY_VALUES:
             error = self.error_messages['invalid_month']
             raise forms.ValidationError(error)
         year = int(data_list[1])
         month = int(data_list[0])
         # find last day of the month
         day = monthrange(year, month)[1]
         return date(year, month, day)
     return None
Example #24
0
 def compress(self, data_list):
     warn_untested()
     if data_list:
         if data_list[1] in forms.fields.EMPTY_VALUES:
             error = self.error_messages['invalid_year']
             raise forms.ValidationError(error)
         if data_list[0] in forms.fields.EMPTY_VALUES:
             error = self.error_messages['invalid_month']
             raise forms.ValidationError(error)
         year = int(data_list[1])
         month = int(data_list[0])
         # find last day of the month
         day = monthrange(year, month)[1]
         return date(year, month, day)
     return None
Example #25
0
    def send_signals(self):
        """Shout for the world to hear whether a txn was successful."""
        if self.flag:
            invalid_ipn_received.send(sender=self)
            payment_was_flagged.send(sender=self)
            return
        else:
            valid_ipn_received.send(sender=self)

        # Transaction signals:
        if self.is_transaction():
            if self.is_refund():
                payment_was_refunded.send(sender=self)
            elif self.is_reversed():
                payment_was_reversed.send(sender=self)
            else:
                payment_was_successful.send(sender=self)
        # Recurring payment signals:
        # XXX: Should these be merged with subscriptions?
        elif self.is_recurring():
            if self.is_recurring_create():
                recurring_create.send(sender=self)
            elif self.is_recurring_payment():
                warn_untested()
                recurring_payment.send(sender=self)
            elif self.is_recurring_cancel():
                recurring_cancel.send(sender=self)
            elif self.is_recurring_skipped():
                recurring_skipped.send(sender=self)
            elif self.is_recurring_failed():
                recurring_failed.send(sender=self)
        # Subscription signals:
        else:
            warn_untested()
            if self.is_subscription_cancellation():
                subscription_cancel.send(sender=self)
            elif self.is_subscription_signup():
                subscription_signup.send(sender=self)
            elif self.is_subscription_end_of_term():
                subscription_eot.send(sender=self)
            elif self.is_subscription_modified():
                subscription_modify.send(sender=self)
Example #26
0
    def process(self, request, item):
        """Do a direct payment."""
        warn_untested()
        from paypal.pro.helpers import PayPalWPP

        wpp = PayPalWPP(request)

        # Change the model information into a dict that PayPal can understand.
        params = model_to_dict(self, exclude=self.ADMIN_FIELDS)
        params['acct'] = self.acct
        params['creditcardtype'] = self.creditcardtype
        params['expdate'] = self.expdate
        params['cvv2'] = self.cvv2
        params.update(item)

        # Create recurring payment:
        if 'billingperiod' in params:
            return wpp.createRecurringPaymentsProfile(params, direct=True)
        # Create single payment:
        else:
            return wpp.doDirectPayment(params)
Example #27
0
    def process(self, request, item):
        """Do a direct payment."""
        warn_untested()
        from paypal.pro.helpers import PayPalWPP

        wpp = PayPalWPP(request)

        # Change the model information into a dict that PayPal can understand.
        params = model_to_dict(self, exclude=self.ADMIN_FIELDS)
        params['acct'] = self.acct
        params['creditcardtype'] = self.creditcardtype
        params['expdate'] = self.expdate
        params['cvv2'] = self.cvv2
        params.update(item)

        # Create recurring payment:
        if 'billingperiod' in params:
            return wpp.createRecurringPaymentsProfile(params, direct=True)
        # Create single payment:
        else:
            return wpp.doDirectPayment(params)
Example #28
0
    def validate_confirm_form(self):
        """
        Third and final step of ExpressCheckout. Request has pressed the confirmation but
        and we can send the final confirmation to PayPal using the data from the POST'ed form.
        """
        wpp = PayPalWPP(self.request)
        pp_data = dict(token=self.request.POST['token'], payerid=self.request.POST['PayerID'])
        self.item.update(pp_data)

        # @@@ This check and call could be moved into PayPalWPP.
        try:
            if self.is_recurring():
                warn_untested()
                nvp = wpp.createRecurringPaymentsProfile(self.item)
            else:
                nvp = wpp.doExpressCheckoutPayment(self.item)
            self.handle_nvp(nvp)
        except PayPalFailure:
            self.context['errors'] = self.errors['processing']
            return self.render_payment_form()
        else:
            return HttpResponseRedirect(self.success_url)
Example #29
0
    def process(self, request, item):
        """Process a PayPal direct payment."""
        warn_untested()
        from paypal.pro.helpers import PayPalWPP

        wpp = PayPalWPP(request)
        params = self.cleaned_data
        params['creditcardtype'] = self.fields['acct'].card_type
        params['expdate'] = self.cleaned_data['expdate'].strftime("%m%Y")
        params['ipaddress'] = request.META.get("REMOTE_ADDR", "")
        params.update(item)

        try:
            # Create single payment:
            if 'billingperiod' not in params:
                wpp.doDirectPayment(params)
            # Create recurring payment:
            else:
                wpp.createRecurringPaymentsProfile(params, direct=True)
        except PayPalFailure:
            return False
        return True
Example #30
0
    def init(self, request, paypal_request, paypal_response):
        """Initialize a PayPalNVP instance from a HttpRequest."""
        if request is not None:
            from paypal.pro.helpers import strip_ip_port
            self.ipaddress = strip_ip_port(request.META.get('REMOTE_ADDR', ''))
            if (hasattr(request, "user") and request.user.is_authenticated):
                self.user = request.user
        else:
            self.ipaddress = ''

        # No storing credit card info.
        query_data = dict((k, v) for k, v in paypal_request.items() if k not in self.RESTRICTED_FIELDS)
        self.query = urlencode(query_data)
        self.response = urlencode(paypal_response)

        # Was there a flag on the play?
        ack = paypal_response.get('ack', False)
        if ack != "Success":
            if ack == "SuccessWithWarning":
                warn_untested()
                self.flag_info = paypal_response.get('l_longmessage0', '')
            else:
                self.set_flag(paypal_response.get('l_longmessage0', ''), paypal_response.get('l_errorcode', ''))
Example #31
0
    def validate_confirm_form(self):
        """
        Third and final step of ExpressCheckout. Request has pressed the confirmation but
        and we can send the final confirmation to PayPal using the data from the POST'ed form.
        """
        wpp = PayPalWPP(self.request)
        pp_data = dict(token=self.request.POST['token'],
                       payerid=self.request.POST['PayerID'])
        self.item.update(pp_data)

        # @@@ This check and call could be moved into PayPalWPP.
        try:
            if self.is_recurring():
                warn_untested()
                nvp = wpp.createRecurringPaymentsProfile(self.item)
            else:
                nvp = wpp.doExpressCheckoutPayment(self.item)
            self.handle_nvp(nvp)
        except PayPalFailure:
            self.context['errors'] = self.errors['processing']
            return self.render_payment_form()
        else:
            return HttpResponseRedirect(self.success_url)
Example #32
0
def process_pdt(request):
    """
    Payment data transfer implementation:
    https://developer.paypal.com/webapps/developer/docs/classic/products/payment-data-transfer/

    This function returns a tuple of (pdt_obj, failed)
    pdt_obj is an object of type PayPalPDT
    failed is a flag that is True if the input data didn't pass basic validation.

    Note: even for failed=False You must still check the pdt_obj is not flagged i.e.
    pdt_obj.flag == False
    """

    pdt_obj = None
    txn_id = request.GET.get('tx')
    failed = False
    if txn_id is not None:
        # If an existing transaction with the id tx exists: use it
        try:
            pdt_obj = PayPalPDT.objects.get(txn_id=txn_id)
        except PayPalPDT.DoesNotExist:
            # This is a new transaction so we continue processing PDT request
            pass

        if pdt_obj is None:
            form = PayPalPDTForm(request.GET)
            if form.is_valid():
                try:
                    pdt_obj = form.save(commit=False)
                except Exception as e:
                    warn_untested()
                    error = repr(e)
                    failed = True
            else:
                warn_untested()
                error = form.errors
                failed = True

            if failed:
                warn_untested()
                pdt_obj = PayPalPDT()
                pdt_obj.set_flag("Invalid form. %s" % error)

            pdt_obj.initialize(request)

            if not failed:
                # The PDT object gets saved during verify
                pdt_obj.verify()
    else:
        pass  # we ignore any PDT requests that don't have a transaction id

    return (pdt_obj, failed)
Example #33
0
def process_pdt(request):
    """
    Payment data transfer implementation:
    https://developer.paypal.com/webapps/developer/docs/classic/products/payment-data-transfer/

    This function returns a tuple of (pdt_obj, failed)
    pdt_obj is an object of type PayPalPDT
    failed is a flag that is True if the input data didn't pass basic validation.

    Note: even for failed=False You must still check the pdt_obj is not flagged i.e.
    pdt_obj.flag == False
    """

    pdt_obj = None
    txn_id = request.GET.get("tx")
    failed = False
    if txn_id is not None:
        # If an existing transaction with the id tx exists: use it
        try:
            pdt_obj = PayPalPDT.objects.get(txn_id=txn_id)
        except PayPalPDT.DoesNotExist:
            # This is a new transaction so we continue processing PDT request
            pass

        if pdt_obj is None:
            form = PayPalPDTForm(request.GET)
            if form.is_valid():
                try:
                    pdt_obj = form.save(commit=False)
                except Exception as e:
                    warn_untested()
                    error = repr(e)
                    failed = True
            else:
                warn_untested()
                error = form.errors
                failed = True

            if failed:
                warn_untested()
                pdt_obj = PayPalPDT()
                pdt_obj.set_flag(f"Invalid form. {error}")

            pdt_obj.initialize(request)

            if not failed:
                # The PDT object gets saved during verify
                pdt_obj.verify()
    else:
        pass  # we ignore any PDT requests that don't have a transaction id

    return (pdt_obj, failed)
Example #34
0
 def is_donation(self):
     warn_untested()
     return self.button_type == self.DONATE
Example #35
0
 def is_subscription_cancellation(self):
     warn_untested()
     return self.txn_type == "subscr_cancel"
Example #36
0
 def is_subscription_end_of_term(self):
     warn_untested()
     return self.txn_type == "subscr_eot"
Example #37
0
 def is_subscription_signup(self):
     warn_untested()
     return self.txn_type == "subscr_signup"
Example #38
0
    def as_p(self):
        warn_untested()
        return mark_safe(u"""
<input type="hidden" name="cmd" value="_s-xclick" />
<input type="hidden" name="encrypted" value="%s" />
        """ % self._encrypt())
Example #39
0
 def is_recurring_suspended_due_to_max_failed_payment(self):
     warn_untested()
     return self.txn_type == "recurring_payment_suspended_due_to_max_failed_payment"
Example #40
0
 def is_transaction(self):
     warn_untested()
     return not self.is_subscription()
Example #41
0
 def is_donation(self):
     warn_untested()
     return self.button_type == self.DONATE
Example #42
0
 def is_subscription(self):
     warn_untested()
     return self.button_type == self.SUBSCRIBE
Example #43
0
 def clean(self, value):
     warn_untested()
     exp = super(CreditCardExpiryField, self).clean(value)
     if date.today() > exp:
         raise forms.ValidationError("The expiration date you entered is in the past.")
     return exp
Example #44
0
def ipn(request):
    """
    PayPal IPN endpoint (notify_url).
    Used by both PayPal Payments Pro and Payments Standard to confirm transactions.
    http://tinyurl.com/d9vu9d

    PayPal IPN Simulator:
    https://developer.paypal.com/cgi-bin/devscr?cmd=_ipn-link-session
    """
    # TODO: Clean up code so that we don't need to set None here and have a lot
    #       of if checks just to determine if flag is set.
    flag = None
    ipn_obj = None

    # Avoid the RawPostDataException. See original issue for details:
    # https://github.com/spookylukey/django-paypal/issues/79
    if not request.META.get('CONTENT_TYPE', '').startswith(
            'application/x-www-form-urlencoded'):
        raise AssertionError(CONTENT_TYPE_ERROR)

    logger.debug("PayPal incoming POST data: %s", request.body)

    # Clean up the data as PayPal sends some weird values such as "N/A"
    # Also, need to cope with custom encoding, which is stored in the body (!).
    # Assuming the tolerant parsing of QueryDict and an ASCII-like encoding,
    # such as windows-1252, latin1 or UTF8, the following will work:
    encoding = request.POST.get('charset', None)

    encoding_missing = encoding is None
    if encoding_missing:
        encoding = DEFAULT_ENCODING

    try:
        data = QueryDict(request.body, encoding=encoding).copy()
    except LookupError:
        warn_untested()
        data = None
        flag = "Invalid form - invalid charset"

    if data is not None:
        if hasattr(PayPalIPN._meta, 'get_fields'):
            date_fields = [f.attname for f in PayPalIPN._meta.get_fields() if f.__class__.__name__ == 'DateTimeField']
        else:
            date_fields = [f.attname for f, m in PayPalIPN._meta.get_fields_with_model()
                           if f.__class__.__name__ == 'DateTimeField']

        for date_field in date_fields:
            if data.get(date_field) == 'N/A':
                del data[date_field]

        form = PayPalIPNForm(data)
        if form.is_valid():
            try:
                # When commit = False, object is returned without saving to DB.
                ipn_obj = form.save(commit=False)
            except Exception as e:
                flag = "Exception while processing. (%s)" % e
        else:
            formatted_form_errors = ["{0}: {1}".format(k, ", ".join(v)) for k, v in form.errors.items()]
            flag = "Invalid form. ({0})".format(", ".join(formatted_form_errors))

    if ipn_obj is None:
        ipn_obj = PayPalIPN()

    # Set query params and sender's IP address
    ipn_obj.initialize(request)

    if flag is not None:
        # We save errors in the flag field
        ipn_obj.set_flag(flag)
    else:
        # Secrets should only be used over SSL.
        if request.is_secure() and 'secret' in request.GET:
            warn_untested()
            ipn_obj.verify_secret(form, request.GET['secret'])
        else:
            ipn_obj.verify()

    ipn_obj.save()
    ipn_obj.send_signals()

    if encoding_missing:
        # Wait until we have an ID to log warning
        logger.warning("No charset passed with PayPalIPN: %s. Guessing %s", ipn_obj.id, encoding)

    return HttpResponse("OKAY")
Example #45
0
 def is_billing_agreement_create(self):
     warn_untested()
     return self.txn_type == "mp_signup"
Example #46
0
def paypal_time(time_obj=None):
    """Returns a time suitable for PayPal time fields."""
    warn_untested()
    if time_obj is None:
        time_obj = time.gmtime()
    return time.strftime(PayPalNVP.TIMESTAMP_FORMAT, time_obj)
Example #47
0
 def is_billing_agreement_cancel(self):
     warn_untested()
     return self.txn_type == "mp_cancel"
Example #48
0
 def verify_secret(self, form_instance, secret):
     """Verifies an IPN payment over SSL using EWP."""
     warn_untested()
     if not check_secret(form_instance, secret):
         self.set_flag("Invalid secret. (%s)") % secret
     self.save()
Example #49
0
 def verify_secret(self, form_instance, secret):
     """Verifies an IPN payment over SSL using EWP."""
     warn_untested()
     if not check_secret(form_instance, secret):
         self.set_flag("Invalid secret. (%s)") % secret
     self.save()
Example #50
0
 def is_billing_agreement_cancel(self):
     warn_untested()
     return self.txn_type == "mp_cancel"
Example #51
0
 def is_recurring_suspended(self):
     warn_untested()
     return self.txn_type == "recurring_payment_suspended"
Example #52
0
 def is_billing_agreement_create(self):
     warn_untested()
     return self.txn_type == "mp_signup"
Example #53
0
 def is_subscription_modified(self):
     warn_untested()
     return self.txn_type == "subscr_modify"
Example #54
0
 def is_billing_agreement(self):
     warn_untested()
     return len(self.mp_id) > 0
Example #55
0
def paypal_time(time_obj=None):
    """Returns a time suitable for PayPal time fields."""
    warn_untested()
    if time_obj is None:
        time_obj = time.gmtime()
    return time.strftime(PayPalNVP.TIMESTAMP_FORMAT, time_obj)
Example #56
0
 def is_recurring_suspended_due_to_max_failed_payment(self):
     warn_untested()
     return self.txn_type == "recurring_payment_suspended_due_to_max_failed_payment"
Example #57
0
 def is_transaction(self):
     warn_untested()
     return not self.is_subscription()
Example #58
0
 def is_billing_agreement(self):
     warn_untested()
     return len(self.mp_id) > 0
Example #59
0
 def is_subscription(self):
     warn_untested()
     return self.button_type == self.SUBSCRIBE
Example #60
0
def get_sha1_hexdigest(salt, raw_password):
    warn_untested()
    return hashlib.sha1(smart_str(salt) + smart_str(raw_password)).hexdigest()