コード例 #1
0
    def get_embed_context(self, context):
        # list countries for billing address form
        context["authorizenet_countries"] = frappe.get_list(
            "Country", fields=["country_name", "name"], ignore_permissions=1)
        default_country = frappe.get_value("System Settings",
                                           "System Settings", "country")
        default_country_doc = next((x
                                    for x in context["authorizenet_countries"]
                                    if x.name == default_country), None)

        country_idx = context["authorizenet_countries"].index(
            default_country_doc)
        context["authorizenet_countries"].pop(country_idx)
        context["authorizenet_countries"] = [
            default_country_doc
        ] + context["authorizenet_countries"]

        context["year"] = datetime.today().year

        # get the authorizenet user record
        authnet_user = get_authorizenet_user()

        if authnet_user:
            context["stored_payments"] = authnet_user.get(
                "stored_payments", [])
コード例 #2
0
def get_context(context):
    context.no_cache = 1

    # get request name from query string
    request_name = frappe.form_dict.get("req")
    # or from pathname, this works better for redirection on auth errors
    if not request_name:
        path_parts = context.get("pathname", "").split('/')
        request_name = path_parts[-1]

    # attempt to fetch AuthorizeNet Request record
    try:
        request = frappe.get_doc("AuthorizeNet Request", request_name)
    except Exception as ex:
        request = None

    # Captured/Authorized transaction redirected to home page
    # TODO: Should we redirec to a "Payment already received" Page?
    if not request or (request and request.get('status')
                       in ("Captured", "Authorized")):
        frappe.local.flags.redirect_location = '/'
        raise frappe.Redirect

    # list countries for billing address form
    context["authorizenet_countries"] = frappe.get_list(
        "Country", fields=["country_name", "name"])

    if request_name and request:
        for key in expected_keys:
            context[key] = request.get(key)

        context["reference_doc"] = frappe.get_doc(
            request.get("reference_doctype"), request.get("reference_docname"))

        context["request_name"] = request_name
        context["year"] = datetime.today().year

        # get the authorizenet user record

        authnet_user = get_authorizenet_user(request.get("payer_name"))
        context["authnet_user"] = authnet_user
        #add=get_primary_address(request.get("payer_name"),'1509101163')
        #context['address']=add
        if authnet_user:
            context["stored_payments"] = authnet_user.get(
                "stored_payments", [])
    else:
        frappe.redirect_to_message(
            _('Some information is missing'),
            _('Looks like someone sent you to an incomplete URL. Please ask them to look into it.'
              ))
        frappe.local.flags.redirect_location = frappe.local.response.location
        raise frappe.Redirect

    return context
コード例 #3
0
    def process_payment(self):
        # used for feedback about which payment was used
        authorizenet_data = {}
        # the current logged in contact
        contact = get_contact()
        # get authorizenet user if available
        authnet_user = get_authorizenet_user()
        # the cc data available
        data = self.process_data

        # get auth keys
        settings = self.get_settings()
        # fetch redirect info
        redirect_to = data.get("notes", {}).get("redirect_to") or None
        redirect_message = data.get("notes",
                                    {}).get("redirect_message") or None

        # uses dummy request doc for unittests as we are only testing processing
        if not data.get("unittest"):
            if data.get("name"):
                request = frappe.get_doc("AuthorizeNet Request",
                                         data.get("name"))
            else:
                # Create request from scratch when embeding form on the fly
                #
                # This allows payment processing without having to pre-create
                # a request first.
                #
                # This path expects all the payment request information to be
                # available!!
                #
                # keys expected: ('amount', 'currency', 'order_id', 'title', \
                #                 'description', 'payer_email', 'payer_name', \
                #                 'reference_docname', 'reference_doctype')
                request = self.build_authorizenet_request(**{ \
                 key: data[key] for key in \
                  ('amount', 'currency', 'order_id', 'title', \
                   'description', 'payer_email', 'payer_name', \
                   'reference_docname', 'reference_doctype') })

                data["name"] = request.get("name")
        else:
            request = frappe.get_doc({"doctype": "AuthorizeNet Request"})

        request.flags.ignore_permissions = 1

        # set the max log level as per settings
        request.max_log_level(self.log_level)

        try:

            if self.card_info:
                # ensure card fields exist
                required_card_fields = [
                    'name_on_card', 'card_number', 'exp_month', 'exp_year',
                    'card_code'
                ]
                for f in required_card_fields:
                    if not self.card_info.get(f):
                        request.status = "Error"
                        return request, None, "Missing field: %s" % f, {}

            # prepare authorize api
            authorize.Configuration.configure(
                authorize.Environment.TEST
                if self.use_sandbox else authorize.Environment.PRODUCTION,
                settings.api_login_id, settings.api_transaction_key)

            # cache billing fields as per authorize api requirements
            billing = authnet_address(self.billing_info)
            if self.shipping_info:
                shipping = authnet_address(self.shipping_info)
            else:
                shipping = None

            # attempt to find valid email address
            email = self.process_data.get("payer_email")

            if email:
                email = email.split(',')[0]

            if "@" not in email and contact:
                email = contact.get("email_id")

                if "@" not in email:
                    if contact and contact.user:
                        email = frappe.get_value("User", contact.user,
                                                 "email_id")

                        if "@" not in email:
                            log("AUTHNET FAILURE! Bad email: {0}".format(
                                email))
                            raise ValueError(
                                "There are no valid emails associated with this customer"
                            )

            # build transaction data
            transaction_data = {
                "order": {
                    "invoice_number": data["order_id"]
                },
                "amount": flt(self.process_data.get("amount")),
                "email": email,
                "description": self.card_info.get("name_on_card"),
                "customer_type": "individual"
            }

            # track ip for tranasction records
            if frappe.local.request_ip:
                transaction_data.update({
                    "extra_options": {
                        "customer_ip": frappe.local.request_ip
                    }
                })

            # get authorizenet profile informatio for stored payments
            authorizenet_profile = self.process_data.get(
                "authorizenet_profile")

            # use card
            # see: https://vcatalano.github.io/py-authorize/transaction.html
            if self.card_info != None:
                # exp formating for sale/auth api
                expiration_date = "{0}/{1}".format(
                    self.card_info.get("exp_month"),
                    self.card_info.get("exp_year"))

                transaction_data.update({
                    "credit_card": {
                        "card_number": self.card_info.get("card_number"),
                        "expiration_date": expiration_date,
                        "card_code": self.card_info.get("card_code")
                    }
                })
            elif authorizenet_profile:

                # if the customer_id isn't provided, then fetch from authnetuser
                if not authorizenet_profile.get("customer_id"):
                    authorizenet_profile["customer_id"] = authnet_user.get(
                        "authorizenet_id")

                # or stored payment
                transaction_data.update({
                    "customer_id":
                    authorizenet_profile.get("customer_id"),
                    "payment_id":
                    authorizenet_profile.get("payment_id")
                })

                # track transaction payment profile ids to return later
                authorizenet_data.update({
                    "customer_id":
                    authorizenet_profile.get("customer_id"),
                    "payment_id":
                    authorizenet_profile.get("payment_id")
                })
            else:
                raise "Missing Credit Card Information"

            name_parts = self.card_info["name_on_card"].split(' ')
            first_name = name_parts[0]
            last_name = " ".join(name_parts[1:])

            # add billing information if available
            if len(billing.keys()):
                transaction_data["billing"] = billing
                transaction_data["billing"]["first_name"] = first_name
                transaction_data["billing"]["last_name"] = last_name

            if shipping and len(shipping.keys()):
                transaction_data["shipping"] = billing
                transaction_data["shipping"]["first_name"] = first_name
                transaction_data["shipping"]["last_name"] = last_name

            # include line items if available
            if self.process_data.get("line_items"):
                transaction_data["line_items"] = self.process_data.get(
                    "line_items")

            request.log_action("Requesting Transaction: %s" % \
             json.dumps(transaction_data), "Debug")

            # performt transaction finally
            result = authorize.Transaction.sale(transaction_data)
            request.log_action(json.dumps(result), "Debug")

            # if all went well, record transaction id
            request.transaction_id = result.transaction_response.trans_id
            request.status = "Captured"
            request.flags.ignore_permissions = 1

        except AuthorizeInvalidError as iex:
            # log validation errors
            request.log_action(frappe.get_traceback(), "Error")
            request.status = "Error"
            error_msg = ""
            errors = []

            if iex.children and len(iex.children) > 0:
                for field_error in iex.children:
                    print(field_error.asdict())
                    for field_name, error in field_error.asdict().iteritems():
                        errors.append(error)

            error_msg = "\n".join(errors)

            request.error_msg = error_msg

        except AuthorizeResponseError as ex:
            # log authorizenet server response errors
            result = ex.full_response
            request.log_action(json.dumps(result), "Debug")
            request.log_action(str(ex), "Error")
            request.status = "Error"
            request.error_msg = ex.text

            redirect_message = str(ex)
            if result and hasattr(result, 'transaction_response'):
                # if there is extra transaction data, log it
                errors = result.transaction_response.errors
                request.log_action(
                    "\n".join([err.error_text for err in errors]), "Error")
                request.log_action(frappe.get_traceback(), "Error")

                request.transaction_id = result.transaction_response.trans_id
                redirect_message = "Success"

            pass

        except Exception as ex:
            log(frappe.get_traceback())
            # any other errors
            request.log_action(frappe.get_traceback(), "Error")
            request.status = "Error"
            request.error_msg = "[UNEXPECTED ERROR]: {0}".format(ex)
            pass

        # now check if we should store payment information on success
        if request.status in ("Captured", "Authorized") and \
         self.card_info and \
         self.card_info.get("store_payment") and \
         contact:

            try:

                # create customer if authnet_user doesn't exist
                if not authnet_user:
                    request.log_action("Creating AUTHNET customer", "Info")

                    customer_result = authorize.Customer.from_transaction(
                        request.transaction_id)

                    request.log_action("Success", "Debug")

                    authnet_user = frappe.get_doc({
                        "doctype":
                        "AuthorizeNet Users",
                        "authorizenet_id":
                        customer_result.customer_id,
                        "contact":
                        contact.name
                    })

                card_store_info = {
                    "card_number": self.card_info.get("card_number"),
                    "expiration_month": self.card_info.get("exp_month"),
                    "expiration_year": self.card_info.get("exp_year"),
                    "card_code": self.card_info.get("card_code"),
                    "billing": self.billing_info
                }

                request.log_action("Storing Payment Information With AUTHNET",
                                   "Info")
                request.log_action(json.dumps(card_store_info), "Debug")

                try:
                    card_result = authorize.CreditCard.create(
                        authnet_user.get("authorizenet_id"), card_store_info)
                except AuthorizeResponseError as ex:
                    card_result = ex.full_response
                    request.log_action(json.dumps(card_result), "Debug")
                    request.log_action(str(ex), "Error")

                    try:
                        # duplicate payment profile
                        if card_result["messages"][0]["message"][
                                "code"] == "E00039":
                            request.log_action(
                                "Duplicate payment profile, ignore", "Error")
                        else:
                            raise ex
                    except:
                        raise ex

                request.log_action("Success: %s" % card_result.payment_id,
                                   "Debug")

                address_short = "{0}, {1} {2}".format(billing.get("city"),
                                                      billing.get("state"),
                                                      billing.get("pincode"))

                card_label = "{0}{1}".format(
                    get_card_accronym(self.card_info.get("card_number")),
                    self.card_info.get("card_number")[-4:])

                authnet_user.flags.ignore_permissions = 1
                authnet_user.append(
                    "stored_payments", {
                        "doctype":
                        "AuthorizeNet Stored Payment",
                        "short_text":
                        "%s %s" % (card_label, address_short),
                        "long_text":
                        "{0}\n{1}\n{2}, {3} {4}\n{5}".format(
                            card_label, billing.get("address", ""),
                            billing.get("city", ""), billing.get("state", ""),
                            billing.get("pincode", ""),
                            frappe.get_value(
                                "Country",
                                filters={
                                    "name": self.billing_info.get("country")
                                },
                                fieldname="country_name")),
                        "address_1":
                        self.billing_info.get("address_1"),
                        "address_2":
                        self.billing_info.get("address_2"),
                        "expires":
                        "{0}-{1}-01".format(self.card_info.get("exp_year"),
                                            self.card_info.get("exp_month")),
                        "city":
                        self.billing_info.get("city"),
                        "state":
                        self.billing_info.get("state"),
                        "postal_code":
                        self.billing_info.get("pincode"),
                        "country":
                        frappe.get_value("Country",
                                         self.billing_info.get("country"),
                                         fieldname="code"),
                        "payment_type":
                        "Card",
                        "authorizenet_payment_id":
                        card_result.payment_id
                    })

                authorizenet_data.update({
                    "customer_id":
                    authnet_user.get("authorizenet_id"),
                    "payment_id":
                    card_result.payment_id
                })

                if not data.get("unittest"):
                    authnet_user.save()

                request.log_action("Stored in DB", "Debug")
            except Exception as exx:
                # any other errors
                request.log_action(frappe.get_traceback(), "Error")
                raise exx

        return request, redirect_to, redirect_message, authorizenet_data
コード例 #4
0
    def process_payment(self):
        # used for feedback about which payment was used
        authorizenet_data = {"error": 0}
        #authorizenet_data = []

        data = self.process_data

        settings = self.get_settings()
        if not data.get("unittest"):
            if data.get("name"):
                request = frappe.get_doc("AuthorizeNet Request",
                                         data.get("name"))
            else:
                request = self.build_authorizenet_request(**{ \
                 key: data[key] for key in \
                  ('amount', 'currency', 'order_id', 'title', \
                  'description', 'payer_email', 'payer_name', \
                  'reference_docname', 'reference_doctype') })
                data["name"] = request.get("name")
        else:
            request = frappe.get_doc({"doctype": "AuthorizeNet Request"})

        try:
            transaction_data = {
                "order": {
                    "invoice_number": data["order_id"],
                    "description": data["description"]
                },
                "amount": flt(self.process_data.get("amount")),
            }
            shipment_charges = {}
            """get_reference= frappe.get_doc(request.reference_doctype,request.reference_docname)						                        
			if request.reference_doctype == "Payment Entry":				 
				if len(get_reference.references) == 1:
					inv_ref=get_reference.references 
					ship_charg=frappe.get_doc(inv_ref[0].reference_doctype,inv_ref[0].reference_name)
					if inv_ref[0].reference_doctype == "Sales Invoice":
						shipment_charges= {
							'amount': ship_charg.shipment_amount,
							'name': ship_charg.shipment_name,
							'description':"",
						}
					elif inv_ref[0].reference_doctype == "Sales order":
						shipment_charges= {
							'amount': ship_charg.shipment_cost,
							'name': ship_charg.shipping_service,
							'description':"",
						}
			elif request.reference_doctype == "Payment Request":
				ship_charg=frappe.get_doc(get_reference.reference_doctype,get_reference.reference_name)
				if get_reference.reference_doctype == "Sales Invoice":
					shipment_charges= {
						'amount': ship_charg.shipment_amount,
						'name': ship_charg.shipment_name,
						'description':"",
					}   
				elif get_reference.reference_doctype == 'Sales order': 
					shipment_charges= {       
						'amount': ship_charg.shipment_cost,
						'name': ship_charg.shipping_service,
						'description':"",  
					}"""
            if shipment_charges:
                transaction_data["shipping_and_handling"] = shipment_charges
            transaction_data["line_items"] = get_line_items(
                request.reference_doctype, request.reference_docname)
            transaction_data["user_fields"] = get_additional_info(
                request.reference_doctype, request.reference_docname)
            if frappe.local.request_ip:
                transaction_data.update({
                    "extra_options": {
                        "customer_ip": frappe.local.request_ip
                    }
                })

            authorize.Configuration.configure(
                authorize.Environment.TEST
                if self.use_sandbox else authorize.Environment.PRODUCTION,
                settings.api_login_id, settings.api_transaction_key)
            """authorize.Configuration.configure(
			authorize.Environment.TEST,
			'6M7Hp5u6',
			'8d5MgF9zB6A272df',  
			)   """

            authnet_user = get_authorizenet_user(request.get("payer_name"))
            authorizenet_profile = self.process_data.get(
                "authorizenet_profile")
            #if user select already saved payment profile then authorizenet_profile is true
            if bool(authorizenet_profile) == False:
                name_parts = request.get("payer_name").split(' ')
                name_on_card = str(self.card_info.get("name_on_card"))
                billing = self.billing_info
                first_name = name_parts[0]
                last_name = " ".join(name_parts[1:])
                address = self.billing_info
                address["first_name"] = first_name[:50]
                address["last_name"] = last_name[:50]
                address["company"] = request.get("payer_name")[:50]
                card_store_info = {
                    "customer_type": "individual",
                    "card_number": self.card_info.get("card_number"),
                    "expiration_month": self.card_info.get("exp_month"),
                    "expiration_year": self.card_info.get("exp_year"),
                    "card_code": self.card_info.get("card_code"),
                    "billing": address
                }
                try:
                    if not authnet_user:
                        #request.log_action("Creating AUTHNET customer", "Info")
                        customer_result = authorize.Customer.create({
                            'email':
                            billing.get("auth_email"),
                            'description':
                            request.get("payer_name"),
                            'customer_type':
                            'individual',
                            'billing':
                            address,
                            'credit_card': {
                                'card_number':
                                self.card_info.get("card_number"),
                                'card_code': self.card_info.get("card_code"),
                                'expiration_month':
                                self.card_info.get("exp_month"),
                                'expiration_year':
                                self.card_info.get("exp_year")
                            }
                        })
                        authnet_user = frappe.new_doc("AuthorizeNet Users")
                        authnet_user.authorizenet_id = customer_result.customer_id
                        authnet_user.contact = request.get("payer_name")
                        authnet_user.email = billing.get("auth_email")
                        authorize_payment_id = customer_result.payment_ids[0]

                    else:
                        card_result = authorize.CreditCard.create(
                            authnet_user.get("authorizenet_id"),
                            card_store_info)
                        authorize_payment_id = card_result.payment_id
                    authorizenet_data.update({
                        "customer_id":
                        authnet_user.get("authorizenet_id"),
                        "payment_id":
                        authorize_payment_id,
                        "name_on_card":
                        name_on_card,
                    })
                    authnet_user.append(
                        "stored_payments", {
                            "doctype":
                            "AuthorizeNet Stored Payment",
                            "long_text":
                            "{0}\n{1}\n{2}, {3} {4}".format(
                                billing.get("address", ""),
                                billing.get("city", ""),
                                billing.get("state", ""), billing.get(
                                    "zip", ""), "United States"),
                            "address_1":
                            self.billing_info.get("address"),
                            "name_on_card":
                            self.card_info.get("name_on_card"),
                            "expires":
                            "{0}-{1}-01".format(
                                self.card_info.get("exp_year"),
                                self.card_info.get("exp_month")),
                            "city":
                            self.billing_info.get("city"),
                            "state":
                            self.billing_info.get("state"),
                            "postal_code":
                            self.billing_info.get("zip"),
                            "country":
                            "United States",
                            "authorizenet_payment_id":
                            authorize_payment_id,
                            "card_type":
                            get_card_accronym(
                                self.card_info.get("card_number")),
                            "card_no":
                            self.card_info.get("card_number")[-4:]
                        })

                    authnet_user.save()
                    transaction_data.update({
                        "customer_id":
                        authnet_user.get("authorizenet_id"),
                        "payment_id":
                        authorize_payment_id,
                    })
                except AuthorizeResponseError as ex:
                    card_result = ex.full_response
                    authorizenet_data.update({
                        "customer_id": "0",
                        "payment_id": "0",
                        "name_on_card": "0",
                        "error": card_result,
                        "card_no": 0,
                        "card_type": 0
                    })
                    request.log_action(json.dumps(card_result), "Debug")
                    request.log_action(str(ex), "Error")
                    try:
                        # duplicate payment profile
                        if card_result["messages"][0]["message"][
                                "code"] == "E00039":
                            request.log_action(
                                "Duplicate payment profile, ignore", "Error")
                        else:
                            raise ex
                    except:
                        raise ex
            else:
                name_on_card = str(authorizenet_profile.get("name_on_card"))
                authorizenet_data.update({
                    "customer_id":
                    authnet_user.get("authorizenet_id"),
                    "payment_id":
                    authorizenet_profile.get("payment_id"),
                    "name_on_card":
                    name_on_card
                })

                transaction_data.update({
                    "email":
                    authorizenet_profile.get("auth_email"),
                    "customer_id":
                    authnet_user.get("authorizenet_id"),
                    "payment_id":
                    authorizenet_profile.get("payment_id"),
                })

            result = authorize.Transaction.sale(transaction_data)
            request.log_action(json.dumps(result), "Debug")
            request.transaction_id = result.transaction_response.trans_id
            request.status = "Captured"
            authorizenet_data.update({
                "card_type":
                result.transaction_response.account_type,
                "card_no":
                result.transaction_response.account_number
            })

        except AuthorizeInvalidError as iex:
            # log validation errors
            request.log_action(frappe.get_traceback(), "Error")
            request.status = "Error"
            request.transaction_id = "0"
            error_msg = ""
            errors = []
            if iex.children and len(iex.children) > 0:
                for field_error in iex.children:
                    #print(field_error.asdict())
                    for error in field_error.asdict().items():
                        errors.append(error)
            #error_msg = "\n".join(errors)
            error_msg = str(errors)
            request.error_msg = error_msg
            authorizenet_data.update({
                "customer_id": 0,
                "payment_id": "0",
                "name_on_card": "0",
                "error": error_msg,
                "card_no": 0,
                "card_type": 0
            })
            #redirect_message=error_msg
            #redirect_to='Error AuthorizeInvalidError'
        except AuthorizeResponseError as ex:
            # log authorizenet server response errors
            result = ex.full_response
            request.log_action(json.dumps(result), "Debug")
            request.log_action(str(ex), "Error")
            request.status = "Error"
            request.error_msg = ex.text
            request.transaction_id = "0"
            authorizenet_data.update({
                "customer_id": 0,
                "payment_id": "0",
                "name_on_card": "0",
                "error": ex.text,
                "card_no": 0,
                "card_type": 0
            })
            #redirect_message = str(ex)
            #redirect_to='Error AuthorizeResponseError'
        except Exception as ex:
            #log(frappe.get_traceback())
            # any other errors
            request.log_action(frappe.get_traceback(), "Error")
            request.status = "Error"
            request.error_msg = "[UNEXPECTED ERROR]: {0}".format(ex)
            #redirect_message ="[UNEXPECTED ERROR]: {0}".format(ex)
            #redirect_to='Error Exception ex'
            authorizenet_data.update({
                "customer_id":
                0,
                "payment_id":
                "0",
                "name_on_card":
                "0",
                "error":
                "[UNEXPECTED ERROR]: {0}".format(ex),
                "card_no":
                0,
                "card_type":
                0
            })
        return request, authorizenet_data