Example #1
0
 def prepare_content(self, purchase, amount):
     self.bill_to = {
         'firstName' : purchase.first_name,
         'lastName' : purchase.last_name,
         'street1': purchase.full_bill_street,
         'city': purchase.bill_city,
         'state' : purchase.bill_state,
         'postalCode' : purchase.bill_postal_code,
         'country': purchase.bill_country,
         'email' : purchase.email,
         'phoneNumber' : purchase.phone,
         }
     exp = purchase.credit_card.expirationDate.split('/')
     self.card = {
         'accountNumber' : purchase.credit_card.decryptedCC,
         'expirationMonth' : exp[0],
         'expirationYear' : exp[1],
         'cvNumber' : purchase.credit_card.ccv
         }
     currency = self.settings['CURRENCY_CODE']
     currency = currency.replace("_", "")
     self.purchase_totals = {
         'currency' : currency,
         'grandTotalAmount' : trunc_decimal(amount, 2),
     }
    def capture_authorized_payment(self, authorization, cim_purchase=None, testing=False):
        """Capture a single payment"""
        assert(cim_purchase)
        if cim_purchase.purchase.authorized_remaining == Decimal('0.00'):
            self.log_extra('No remaining authorizations on %s', cim_purchase)
            return ProcessorResult(self.key, True, _("Already complete"))

        if authorization:
            amount = authorization.amount

        remaining = authorization.remaining
        if amount == NOTSET or amount > remaining:
            if amount != NOTSET:
                self.log_extra('Adjusting auth amount from %s to %s', amount, remaining)
            amount = trunc_decimal(remaining, 2)

        self.log_extra('Capturing Authorization #%i of %s', authorization.id, amount)
        results = None
        if authorization.transaction_id:
            data = {'transaction_id' : authorization.transaction_id, 'authorization' : authorization}
            if hasattr(authorization, 'payment_profile_id') and authorization.payment_profile_id is not None:
                data['payment_profile_id'] = authorization.payment_profile_id
            if hasattr(authorization, 'customer_profile_id') and authorization.customer_profile_id is not None:
                data['customer_profile_id'] = authorization.customer_profile_id
            results = self.send_post(data, self.TRANS_CAPTURE, cim_purchase, amount, testing)
        
        return results
 def prepare_post(self, purchase, amount):
     
     invoice = "%s" % purchase.id
     failct = purchase.paymentfailures.count()
     if failct > 0:
         invoice = "%s_%i" % (invoice, failct)
     
     try:
         cc = purchase.credit_card
         balance = trunc_decimal(purchase.remaining, 2)
         self.packet['VendorTxCode'] = invoice
         self.packet['Amount'] = balance
         self.packet['Description'] = 'Online purchase'
         self.packet['CardType'] = cc.credit_type
         self.packet['CardHolder'] = cc.card_holder
         self.packet['CardNumber'] = cc.decryptedCC
         self.packet['ExpiryDate'] = '%02d%s' % (cc.expire_month, str(cc.expire_year)[2:])
         if cc.start_month is not None:
             self.packet['StartDate'] = '%02d%s' % (cc.start_month, str(cc.start_year)[2:])
         if cc.ccv is not None and cc.ccv != "":
             self.packet['CV2'] = cc.ccv
         if cc.issue_num is not None and cc.issue_num != "":
             self.packet['IssueNumber'] = cc.issue_num #'%02d' % int(cc.issue_num)
         addr = [purchase.bill_street1, purchase.bill_street2, purchase.bill_city, purchase.bill_state]
         self.packet['BillingAddress'] = ', '.join(addr)
         self.packet['BillingPostCode'] = purchase.bill_postal_code
     except Exception, e:
         self.log.error('preparing data, got error: %s\nData: %s', e, purchase)
         self.valid = False
         return
Example #4
0
    def get_prior_auth_data(self, authorization, amount=NOTSET):
        """Build the dictionary needed to process a prior auth capture."""
        trans = {'authorization': authorization}
        remaining = authorization.remaining
        if amount == NOTSET or amount > remaining:
            if amount != NOTSET:
                self.log_extra('Adjusting auth amount from %s to %s', amount,
                               remaining)
            amount = remaining

        balance = trunc_decimal(amount, 2)
        trans['amount'] = amount

        if self.is_live():
            conn = self.settings["CONNECTION"]
            self.log_extra('Using live connection.')
        else:
            testflag = 'TRUE'
            conn = self.settings["CONNECTION_TEST"]
            self.log_extra('Using test connection.')

        if self.settings["SIMULATE"]:
            testflag = 'TRUE'
        else:
            testflag = 'FALSE'

        trans['connection'] = conn

        trans['configuration'] = {
            'x_login': self.settings["LOGIN"],
            'x_tran_key': self.settings["TRANKEY"],
            'x_version': '3.1',
            'x_relay_response': 'FALSE',
            'x_test_request': testflag,
            'x_delim_data': 'TRUE',
            'x_delim_char': '|',
            'x_type': 'PRIOR_AUTH_CAPTURE',
            'x_trans_id': authorization.transaction_id
        }

        self.log_extra('prior auth configuration: %s', trans['configuration'])

        trans['transactionData'] = {
            'x_amount': balance,
        }

        part1 = urlencode(trans['configuration'])
        postdata = part1 + "&" + urlencode(trans['transactionData'])
        trans['postString'] = postdata

        self.log_extra('prior auth poststring: %s', postdata)
        trans['logPostString'] = postdata

        return trans
    def get_prior_auth_data(self, authorization, amount=NOTSET):
        """Build the dictionary needed to process a prior auth capture."""
        trans = {'authorization' : authorization}
        remaining = authorization.remaining
        if amount == NOTSET or amount > remaining:
            if amount != NOTSET:
                self.log_extra('Adjusting auth amount from %s to %s', amount, remaining)
            amount = remaining
        
        balance = trunc_decimal(amount, 2)
        trans['amount'] = amount
        
        if self.is_live():
            conn = self.settings["CONNECTION"]
            self.log_extra('Using live connection.')
        else:
            testflag = 'TRUE'
            conn = self.settings["CONNECTION_TEST"]
            self.log_extra('Using test connection.')
            
        if self.settings["SIMULATE"]:
            testflag = 'TRUE'
        else:
            testflag = 'FALSE'

        trans['connection'] = conn

        trans['configuration'] = {
            'x_login' : self.settings["LOGIN"],
            'x_tran_key' : self.settings["TRANKEY"],
            'x_version' : '3.1',
            'x_relay_response' : 'FALSE',
            'x_test_request' : testflag,
            'x_delim_data' : 'TRUE',
            'x_delim_char' : '|',
            'x_type': 'PRIOR_AUTH_CAPTURE',
            'x_trans_id' : authorization.transaction_id
            }
        
        self.log_extra('prior auth configuration: %s', trans['configuration'])
                
        trans['transactionData'] = {
            'x_amount' : balance,
            }

        part1 = urlencode(trans['configuration']) 
        postdata = part1 + "&" + urlencode(trans['transactionData'])
        trans['postString'] = postdata
        
        self.log_extra('prior auth poststring: %s', postdata)
        trans['logPostString'] = postdata
        
        return trans
Example #6
0
    def prepare_post(self, purchase, amount):

        invoice = "%s" % purchase.id
        failct = purchase.paymentfailures.count()
        if failct > 0:
            invoice = "%s_%i" % (invoice, failct)

        try:
            cc = purchase.credit_card
            balance = trunc_decimal(purchase.remaining, 2)
            self.packet['VendorTxCode'] = invoice
            self.packet['Amount'] = balance
            self.packet['Description'] = 'Online purchase'
            self.packet['CardType'] = cc.credit_type
            self.packet['CardHolder'] = cc.card_holder
            self.packet['CardNumber'] = cc.decryptedCC
            self.packet['ExpiryDate'] = '%02d%s' % (cc.expire_month,
                                                    str(cc.expire_year)[2:])
            if cc.start_month is not None:
                self.packet['StartDate'] = '%02d%s' % (cc.start_month,
                                                       str(cc.start_year)[2:])
            if cc.ccv is not None and cc.ccv != "":
                self.packet['CV2'] = cc.ccv
            if cc.issue_num is not None and cc.issue_num != "":
                self.packet[
                    'IssueNumber'] = cc.issue_num  #'%02d' % int(cc.issue_num)
            addr = [
                purchase.bill_street1, purchase.bill_street2,
                purchase.bill_city, purchase.bill_state
            ]
            self.packet['BillingAddress'] = ', '.join(addr)
            self.packet['BillingPostCode'] = purchase.bill_postal_code
        except Exception, e:
            self.log.error('preparing data, got error: %s\nData: %s', e,
                           purchase)
            self.valid = False
            return
Example #7
0
    def get_standard_charge_data(self,
                                 purchase=None,
                                 amount=NOTSET,
                                 authorize=False):
        """Build the dictionary needed to process a credit card charge"""
        assert (purchase)
        trans = {}
        if amount == NOTSET:
            amount = purchase.total

        balance = trunc_decimal(amount, 2)
        trans['amount'] = balance

        if self.is_live():
            conn = self.settings['CONNECTION']
            self.log_extra('Using live connection.')
        else:
            testflag = 'TRUE'
            conn = self.settings['CONNECTION_TEST']
            self.log_extra('Using test connection.')

        if self.settings['SIMULATE']:
            testflag = 'TRUE'
        else:
            testflag = 'FALSE'

        trans['connection'] = conn

        trans['authorize_only'] = authorize

        if not authorize:
            transaction_type = 'AUTH_CAPTURE'
        else:
            transaction_type = 'AUTH_ONLY'

        trans['configuration'] = {
            'x_login': self.settings['LOGIN'],
            'x_tran_key': self.settings['TRANKEY'],
            'x_version': '3.1',
            'x_relay_response': 'FALSE',
            'x_test_request': testflag,
            'x_delim_data': 'TRUE',
            'x_delim_char': '|',
            'x_type': transaction_type,
            'x_method': 'CC',
        }

        self.log_extra('standard charges configuration: %s',
                       trans['configuration'])

        trans['custBillData'] = {
            'x_first_name': purchase.first_name,
            'x_last_name': purchase.last_name,
            'x_address': purchase.full_bill_street,
            'x_city': purchase.bill_city,
            'x_state': purchase.bill_state,
            'x_zip': purchase.bill_postal_code,
            'x_country': purchase.bill_country,
            'x_phone': purchase.phone,
            'x_email': purchase.email,
        }

        self.log_extra('standard charges configuration: %s',
                       trans['custBillData'])

        invoice = "%s" % purchase.orderno
        failct = purchase.paymentfailures.count()
        if failct > 0:
            invoice = "%s_%i" % (invoice, failct)

        if not self.is_live():
            # add random test id to this, for testing repeatability
            invoice = "%s_test_%s_%i" % (invoice,
                                         datetime.now().strftime('%m%d%y'),
                                         random.randint(1, 1000000))

        card = purchase.credit_card
        cc = card.decryptedCC
        ccv = card.ccv
        if not self.is_live() and cc == '4222222222222':
            if ccv == '222':
                self.log_extra('Setting a bad ccv number to force an error')
                ccv = '1'
            else:
                self.log_extra(
                    'Setting a bad credit card number to force an error')
                cc = '1234'
        trans['transactionData'] = {
            'x_amount': balance,
            'x_card_num': cc,
            'x_exp_date': card.expirationDate,
            'x_card_code': ccv,
            'x_invoice_num': invoice
        }

        part1 = urlencode(trans['configuration']) + "&"
        part2 = "&" + urlencode(trans['custBillData'])
        trans['postString'] = part1 + urlencode(
            trans['transactionData']) + part2

        redactedData = {
            'x_amount': balance,
            'x_card_num': card.display_cc,
            'x_exp_date': card.expirationDate,
            'x_card_code': "REDACTED",
            'x_invoice_num': invoice
        }
        self.log_extra('standard charges transactionData: %s', redactedData)
        trans['logPostString'] = part1 + urlencode(redactedData) + part2

        return trans
Example #8
0
    def get_recurring_charge_data(self, purchase=None, testing=False):
        """Build the list of dictionaries needed to process a recurring charge.
        
        Because Authorize can only take one subscription at a time, we build a list
        of the transaction dictionaries, for later sequential posting.
        """
        assert (purchase)
        if not self.settings['ARB']:
            return []

        # get all subscriptions from the order
        subscriptions = purchase.recurring_lineitems()

        if len(subscriptions) == 0:
            self.log_extra('No subscription items')
            return []

        # set up the base dictionary
        trans = {}

        if self.is_live():
            conn = self.settings['ARB_CONNECTION']
            self.log_extra('Using live recurring charge connection.')
        else:
            conn = self.settings['ARB_CONNECTION_TEST']
            self.log_extra('Using test recurring charge connection.')

        trans['connection'] = conn
        trans['config'] = {
            'merchantID': self.settings['LOGIN'],
            'transactionKey': self.settings['TRANKEY'],
            'shop_name': self.settings['STORE_NAME'],
        }
        trans['purchase'] = purchase
        cc = self.purchase.credit_card
        trans['card'] = cc
        trans['card_expiration'] = "%4i-%02i" % (cc.expire_year,
                                                 cc.expire_month)

        translist = []
        # remove
        for subscription in subscriptions:
            lineitem = subscription.lineitem

            subtrans = trans.copy()
            subtrans['subscription'] = subscription
            subtrans['product'] = lineitem.name

            if subscription.trial:
                trial_amount = lineitem.total
                trial_tax = lineitem.tax
                trial_shipping = lineitem.shipping
                amount = subscription.recurring_price()
                trial_occurrences = subscription.trial_times
            else:
                trial_occurrences = 0
                trial_amount = Decimal('0.00')
                amount = subscription.recurring_price

            occurrences = subscription.recurring_times + subscription.trial_times
            if occurrences > 9999:
                occurrences = 9999

            subtrans['occurrences'] = subscription.recurring_times
            subtrans['trial_amount'] = subscription.trial_price
            subtrans['trial_occurrences'] = trial_occurrences
            subtrans['amount'] = trunc_decimal(amount, 2)
            if amount > Decimal('0.00'):
                charged_today = trial_amount
            else:
                charged_today = amount

            charged_today = trunc_decimal(charged_today, 2)

            subtrans['charged_today'] = charged_today
            translist.append(subtrans)

        return translist
Example #9
0
    def create(self, request):
        time_format = "%Y-%m-%d %H:%M:%S"
        attrs = self.flatten_dict(request.POST)
        user = request.user

        #log.debug(attrs.get('cdr'))

        #xml_cdr = Soup(request.raw_post_data)
        #parser = etree.XMLParser(remove_blank_text=True)
        #root = "<root><tag>text</tag><aa><bb>bbb</bb><cc>ccc</cc></aa></root>"
        #tree = etree.fromstring(root, parser)
        #return rc.NOT_HERE
        if user.has_perm("cdr.add_cdr"):
            try:
                xml_cdr = Soup(attrs.get('cdr'))

                if xml_cdr.cdr.callflow.caller_profile.caller_id_number is not None:
                    caller_id_number=xml_cdr.cdr.callflow.caller_profile.caller_id_number.string
                else:
                    caller_id_number='000000'
                if xml_cdr.cdr.callflow.caller_profile.caller_id_name.string is not None:
                    caller_id_name = xml_cdr.cdr.callflow.caller_profile.caller_id_name.string
                else:
                    caller_id_name = caller_id_number
                new_cdr = Cdr(caller_id_name=caller_id_name, caller_id_number=caller_id_number)
                #log.debug("caller_id_number: {0} caller_id_name: {1}".format(caller_id_number, caller_id_name))
                #new_cdr.procesed = 1
                # TODO: New stats (n CDRs) rtcp_packet_count and rtcp_octet_count
                if xml_cdr.cdr.variables.lcr_rate is not None:
                    log.debug("lcr_rate %s" % xml_cdr.cdr.variables.lcr_rate.string)
                    new_cdr.lcr_rate = trunc_decimal(xml_cdr.cdr.variables.lcr_rate.string, 4)
                if xml_cdr.cdr.variables.lcr_currency is not None:
                    new_cdr.lprice_currency = xml_cdr.cdr.variables.lcr_currency.string
                else:
                    new_cdr.lprice_currency = "UAH"
                if xml_cdr.cdr.variables.lcr_price is not None:
                    new_cdr.lprice = trunc_decimal(xml_cdr.cdr.variables.lcr_price.string, 4)
                else:
                    new_cdr.lprice = trunc_decimal("0.18", 4)

                if xml_cdr.cdr.variables.lcr_name is not None:
                    new_cdr.lcr_name = xml_cdr.cdr.variables.lcr_name.string
                if xml_cdr.cdr.variables.lcr_digits is not None:
                    new_cdr.lcr_digits = int(xml_cdr.cdr.variables.lcr_digits.string)
                if xml_cdr.cdr.variables.lcr_carrier is not None:
                    log.debug("lcr_carrier %s" % xml_cdr.cdr.variables.lcr_carrier.string)
                    new_cdr.lcr_carrier = xml_cdr.cdr.variables.lcr_carrier.string

                if xml_cdr.cdr.variables.lcr_direction is not None and xml_cdr.cdr.variables.lcr_direction.string == 'in':
                    # входящий звонок
                    new_cdr.direction = 1
                    new_cdr.nibble_rate = trunc_decimal("0.0", 4)
                elif xml_cdr.cdr.variables.lcr_direction is not None and xml_cdr.cdr.variables.lcr_direction.string == 'out':
                    # исходящий звонок
                    new_cdr.direction = 2
                    if xml_cdr.cdr.variables.nibble_rate is not None:
                        log.debug("nibble_rate %s" % xml_cdr.cdr.variables.nibble_rate.string)
                        new_cdr.nibble_rate = trunc_decimal(xml_cdr.cdr.variables.nibble_rate.string, 4)
                    else:
                        new_cdr.nibble_rate = trunc_decimal("0.0", 4)
                else:
                    new_cdr.direction = 0
                    new_cdr.nibble_rate = trunc_decimal("0.0", 4)
                if xml_cdr.cdr.variables.nibble_current_balance is not None:
                    #<nibble_total_billed>0.087786</nibble_total_billed>
                    log.debug("nibble_current_balance %s" % xml_cdr.cdr.variables.nibble_current_balance.string)
                    new_cdr.nibble_current_balance = trunc_decimal(xml_cdr.cdr.variables.nibble_current_balance.string, 6)
                if xml_cdr.cdr.variables.nibble_tariff is not None:
                    new_cdr.nibble_tariff = int(xml_cdr.cdr.variables.nibble_tariff.string)
                if xml_cdr.cdr.variables.nibble_account is not None:
                    new_cdr.nibble_account = int(xml_cdr.cdr.variables.nibble_account.string)
                if xml_cdr.cdr.variables.site_id is not None:
                    new_cdr.site_id = int(xml_cdr.cdr.variables.site_id.string)
                if xml_cdr.cdr.variables.billusec is not None:
                    new_cdr.billusec = int(xml_cdr.cdr.variables.billusec.string)
                    log.debug("billusec: %i" % int(xml_cdr.cdr.variables.billusec.string))

                #elif xml_cdr.cdr.channel_data.direction is not None:
                    #log.debug("direction %s" % xml_cdr.cdr.channel_data.direction.string)
                    #if xml_cdr.cdr.channel_data.direction.string == 'inbound':
                #new_cdr.direction = 1
                    #elif xml_cdr.cdr.channel_data.direction.string == 'outbound':
                #new_cdr.direction = 2
                #l.debug("billsec: %i %i" % xml_cdr.cdr.variables.billsec, xml_cdr.cdr.variables.billmsec)

                if xml_cdr.cdr.variables.accountcode is not None:
                    log.debug("accountcode %s" % xml_cdr.cdr.variables.accountcode.string)
                    new_cdr.accountcode = xml_cdr.cdr.variables.accountcode.string
                else:
                    new_cdr.accountcode = "none"
                if xml_cdr.cdr.variables.sip_received_ip is not None:
                    log.debug("sip_received_ip %s" % xml_cdr.cdr.variables.sip_received_ip.string)
                    new_cdr.sip_received_ip = xml_cdr.cdr.variables.sip_received_ip.string
                if xml_cdr.cdr.variables.number_alias is not None:
                    log.debug("number_alias %s" % xml_cdr.cdr.variables.number_alias.string)
                    new_cdr.number_alias = xml_cdr.cdr.variables.number_alias.string

                new_cdr.destination_number = xml_cdr.cdr.callflow.caller_profile.destination_number.string
                log.debug("destination_number %s" % xml_cdr.cdr.callflow.caller_profile.destination_number.string)
                new_cdr.context = xml_cdr.cdr.callflow.caller_profile.context.string
                log.debug("context %s" % xml_cdr.cdr.callflow.caller_profile.context.string)
                new_cdr.start_timestamp = datetime.datetime.utcfromtimestamp(
                        time.mktime(time.strptime(urllib.unquote(xml_cdr.cdr.variables.start_stamp.string), time_format)))
                log.debug("start_stamp: %s" % new_cdr.start_timestamp)

                if xml_cdr.cdr.variables.answer_stamp is not None:
                    new_cdr.answer_timestamp = datetime.datetime.utcfromtimestamp(time.mktime(time.strptime(urllib.unquote(xml_cdr.cdr.variables.answer_stamp.string), time_format)))
                else:
                    new_cdr.answer_timestamp = new_cdr.start_timestamp
                log.debug("answer_stamp:{0}".format(new_cdr.answer_timestamp))
                if xml_cdr.cdr.variables.end_stamp is not None:
                    new_cdr.end_timestamp = datetime.datetime.utcfromtimestamp(time.mktime(time.strptime(urllib.unquote(xml_cdr.cdr.variables.end_stamp.string), time_format)))
                else:
                    new_cdr.end_timestamp = new_cdr.answer_timestamp
                log.debug("answer_stamp:{0}".format(new_cdr.end_timestamp))
                try:
                    new_cdr.duration = xml_cdr.cdr.variables.duration.string
                except Exception as e:
                    log.error(e)
                    new_cdr.duration = '0'
                log.debug("duration: {0}".format(new_cdr.duration))
                new_cdr.billsec = int(xml_cdr.cdr.variables.billsec.string)
                log.debug("billsec {0}".format(xml_cdr.cdr.variables.billsec.string))
                new_cdr.hangup_cause = xml_cdr.cdr.variables.hangup_cause.string
                log.debug("hangup_cause {0}".format(xml_cdr.cdr.variables.hangup_cause.string))
                new_cdr.uuid = xml_cdr.cdr.callflow.caller_profile.uuid.string
                log.debug("uuid {0}".format(xml_cdr.cdr.callflow.caller_profile.uuid.string))
                try:
                    new_cdr.read_codec = xml_cdr.cdr.variables.read_codec.string
                except Exception as e:
                    #log.error(e)
                    # TODO: add to None
                    new_cdr.read_codec = 'PCMA'
                log.debug("read_codec{0}".format(new_cdr.read_codec))
                try:
                    new_cdr.write_codec = xml_cdr.cdr.variables.write_codec.string
                except Exception as e:
                    #log.error(e)
                    new_cdr.write_codec = new_cdr.read_codec
                log.debug("write_codec {0}".format(new_cdr.write_codec))

                if xml_cdr.cdr.variables.rtp_audio_in_raw_bytes is not None:
                    new_cdr.rtp_audio_in_raw_bytes = int(xml_cdr.cdr.variables.rtp_audio_in_raw_bytes.string)
                if xml_cdr.cdr.variables.rtp_audio_in_media_bytes is not None:
                    new_cdr.rtp_audio_in_media_bytes = int(xml_cdr.cdr.variables.rtp_audio_in_media_bytes.string)
                if xml_cdr.cdr.variables.rtp_audio_in_packet_count is not None:
                    new_cdr.rtp_audio_in_packet_count = int(xml_cdr.cdr.variables.rtp_audio_in_packet_count.string)
                if xml_cdr.cdr.variables.rtp_audio_in_media_packet_count is not None:
                    new_cdr.rtp_audio_in_media_packet_count = int(
                            xml_cdr.cdr.variables.rtp_audio_in_media_packet_count.string)
                if xml_cdr.cdr.variables.rtp_audio_in_skip_packet_count is not None:
                    new_cdr.rtp_audio_in_skip_packet_count = int(
                            xml_cdr.cdr.variables.rtp_audio_in_skip_packet_count.string)
                if xml_cdr.cdr.variables.rtp_audio_in_jb_packet_count is not None:
                    new_cdr.rtp_audio_in_jb_packet_count = int(xml_cdr.cdr.variables.rtp_audio_in_jb_packet_count.string)
                if xml_cdr.cdr.variables.rtp_audio_in_dtmf_packet_count is not None:
                    new_cdr.rtp_audio_in_dtmf_packet_count = int(
                            xml_cdr.cdr.variables.rtp_audio_in_dtmf_packet_count.string)
                if xml_cdr.cdr.variables.rtp_audio_in_cng_packet_count is not None:
                    new_cdr.rtp_audio_in_cng_packet_count = int(xml_cdr.cdr.variables.rtp_audio_in_cng_packet_count.string)
                if xml_cdr.cdr.variables.rtp_audio_in_flush_packet_count is not None:
                    new_cdr.rtp_audio_in_flush_packet_count = int(
                            xml_cdr.cdr.variables.rtp_audio_in_flush_packet_count.string)
                if xml_cdr.cdr.variables.rtp_audio_out_raw_bytes is not None:
                    new_cdr.rtp_audio_out_raw_bytes = int(xml_cdr.cdr.variables.rtp_audio_out_raw_bytes.string)
                if xml_cdr.cdr.variables.rtp_audio_out_media_bytes is not None:
                    new_cdr.rtp_audio_out_media_bytes = int(xml_cdr.cdr.variables.rtp_audio_out_media_bytes.string)
                if xml_cdr.cdr.variables.rtp_audio_out_packet_count is not None:
                    new_cdr.rtp_audio_out_packet_count = int(xml_cdr.cdr.variables.rtp_audio_out_packet_count.string)
                if xml_cdr.cdr.variables.rtp_audio_out_media_packet_count is not None:
                    new_cdr.rtp_audio_out_media_packet_count = int(
                            xml_cdr.cdr.variables.rtp_audio_out_media_packet_count.string)
                if xml_cdr.cdr.variables.rtp_audio_out_skip_packet_count is not None:
                    new_cdr.rtp_audio_out_skip_packet_count = int(
                            xml_cdr.cdr.variables.rtp_audio_out_skip_packet_count.string)
                if xml_cdr.cdr.variables.rtp_audio_out_dtmf_packet_count is not None:
                    new_cdr.rtp_audio_out_dtmf_packet_count = int(
                            xml_cdr.cdr.variables.rtp_audio_out_dtmf_packet_count.string)
                if xml_cdr.cdr.variables.rtp_audio_out_cng_packet_count is not None:
                    new_cdr.rtp_audio_out_cng_packet_count = int(
                            xml_cdr.cdr.variables.rtp_audio_out_cng_packet_count.string)
                if xml_cdr.cdr.variables.rtp_audio_rtcp_packet_count is not None:
                    new_cdr.rtp_audio_rtcp_packet_count = int(xml_cdr.cdr.variables.rtp_audio_rtcp_packet_count.string)
                if xml_cdr.cdr.variables.rtp_audio_rtcp_octet_count is not None:
                    new_cdr.rtp_audio_rtcp_octet_count = int(xml_cdr.cdr.variables.rtp_audio_rtcp_octet_count.string)

                if xml_cdr.cdr.variables.nibble_total_billed is not None:
                    #<nibble_total_billed>0.087786</nibble_total_billed>
                    log.debug("nibble_total_billed {0}".format(xml_cdr.cdr.variables.nibble_total_billed.string))
                    new_cdr.nibble_total_billed = trunc_decimal(xml_cdr.cdr.variables.nibble_total_billed.string, 6)
                #sip_user_agent
                #if new_cdr.lcr_rate > Decimal("0") and new_cdr.nibble_rate > Decimal("0") and new_cdr.billsec > 0:
                if new_cdr.lcr_rate > Decimal("0") and new_cdr.billusec > 0:
                    #new_cdr.cash = new_cdr.nibble_rate/60*new_cdr.billsec
                    new_cdr.cash = new_cdr.lcr_rate / 1000000 / 60 * new_cdr.billusec
                if new_cdr.cash is not None and new_cdr.nibble_total_billed is not None:
                    new_cdr.marja = new_cdr.cash - new_cdr.nibble_total_billed
                    #try:
                #from fsb.billing.models import Balance
                #bal = Balance.objects.get(accountcode__username__exact=new_cdr.accountcode)
                #bal.cash -= new_cdr.cash
                #bal.save()
                    #except:
                #pass
                #<endpoint_disposition>ANSWER</endpoint_disposition>
                #<proto_specific_hangup_cause>sip%3A200</proto_specific_hangup_cause>
                #<sip_hangup_phrase>OK</sip_hangup_phrase>
                ##        <sip_use_codec_name>GSM</sip_use_codec_name>
                ##        <sip_use_codec_rate>8000</sip_use_codec_rate>
                ##        <sip_use_codec_ptime>20</sip_use_codec_ptime>
                ##        <read_codec>GSM</read_codec>
                ##        <read_rate>8000</read_rate>
                ##        <write_codec>GSM</write_codec>
                ##        <write_rate>8000</write_rate>
                new_cdr.save()

                log.debug("caller_id_name {0}".format(new_cdr.caller_id_name))
                log.debug("caller_id_number {0}".format(new_cdr.caller_id_number))
                #log.debug("bridge_channel %s" % new_cdr.bridge_channel)
                #resp = rc.CREATED
                resp = rc.ALL_OK
                #resp.write(endpoint)
                return resp
            except Exception as e:
                log.error(e)
                return rc.NOT_HERE
        else:
            return rc.FORBIDDEN
    def get_standard_charge_data(self, purchase=None, amount=NOTSET, authorize=False):
        """Build the dictionary needed to process a credit card charge"""
        assert(purchase)
        trans = {}
        if amount == NOTSET:
            amount = purchase.total
            
        balance = trunc_decimal(amount, 2)
        trans['amount'] = balance
        
        if self.is_live():
            conn = self.settings['CONNECTION']
            self.log_extra('Using live connection.')
        else:
            testflag = 'TRUE'
            conn = self.settings['CONNECTION_TEST']
            self.log_extra('Using test connection.')
            
        if self.settings['SIMULATE']:
            testflag = 'TRUE'
        else:
            testflag = 'FALSE'

        trans['connection'] = conn
            
        trans['authorize_only'] = authorize

        if not authorize:
            transaction_type = 'AUTH_CAPTURE'
        else:
            transaction_type = 'AUTH_ONLY'
                        
        trans['configuration'] = {
            'x_login' : self.settings['LOGIN'],
            'x_tran_key' : self.settings['TRANKEY'],
            'x_version' : '3.1',
            'x_relay_response' : 'FALSE',
            'x_test_request' : testflag,
            'x_delim_data' : 'TRUE',
            'x_delim_char' : '|',
            'x_type': transaction_type,
            'x_method': 'CC',
            }
        
        self.log_extra('standard charges configuration: %s', trans['configuration'])
        
        trans['custBillData'] = {
            'x_first_name' : purchase.first_name,
            'x_last_name' : purchase.last_name,
            'x_address': purchase.full_bill_street,
            'x_city': purchase.bill_city,
            'x_state' : purchase.bill_state,
            'x_zip' : purchase.bill_postal_code,
            'x_country': purchase.bill_country,
            'x_phone' : purchase.phone,
            'x_email' : purchase.email,
            }
    
        self.log_extra('standard charges configuration: %s', trans['custBillData'])
        
        invoice = "%s" % purchase.orderno
        failct = purchase.paymentfailures.count()
        if failct > 0:
            invoice = "%s_%i" % (invoice, failct)

        if not self.is_live():
            # add random test id to this, for testing repeatability
            invoice = "%s_test_%s_%i" % (invoice,  datetime.now().strftime('%m%d%y'), random.randint(1,1000000))
        
        card = purchase.credit_card
        cc = card.decryptedCC
        ccv = card.ccv
        if not self.is_live() and cc == '4222222222222':
            if ccv == '222':
                self.log_extra('Setting a bad ccv number to force an error')
                ccv = '1'
            else:
                self.log_extra('Setting a bad credit card number to force an error')
                cc = '1234'
        trans['transactionData'] = {
            'x_amount' : balance,
            'x_card_num' : cc,
            'x_exp_date' : card.expirationDate,
            'x_card_code' : ccv,
            'x_invoice_num' : invoice
            }

        part1 = urlencode(trans['configuration']) + "&"
        part2 = "&" + urlencode(trans['custBillData'])
        trans['postString'] = part1 + urlencode(trans['transactionData']) + part2
        
        redactedData = {
            'x_amount' : balance,
            'x_card_num' : card.display_cc,
            'x_exp_date' : card.expirationDate,
            'x_card_code' : "REDACTED",
            'x_invoice_num' : invoice
        }
        self.log_extra('standard charges transactionData: %s', redactedData)
        trans['logPostString'] = part1 + urlencode(redactedData) + part2
        
        return trans
    def get_recurring_charge_data(self, purchase=None, testing=False):
        """Build the list of dictionaries needed to process a recurring charge.
        
        Because Authorize can only take one subscription at a time, we build a list
        of the transaction dictionaries, for later sequential posting.
        """
        assert(purchase)
        if not self.settings['ARB']:
            return []
        
        # get all subscriptions from the order
        subscriptions = purchase.recurring_lineitems()
        
        if len(subscriptions) == 0:
            self.log_extra('No subscription items')
            return []

        # set up the base dictionary
        trans = {}

        if self.is_live():
            conn = self.settings['ARB_CONNECTION']
            self.log_extra('Using live recurring charge connection.')
        else:
            conn = self.settings['ARB_CONNECTION_TEST']
            self.log_extra('Using test recurring charge connection.')
                
        trans['connection'] = conn
        trans['config'] = {
            'merchantID' : self.settings['LOGIN'],
            'transactionKey' : self.settings['TRANKEY'],
            'shop_name' : self.settings['STORE_NAME'],
        }
        trans['purchase'] = purchase
        cc = self.purchase.credit_card
        trans['card'] = cc
        trans['card_expiration'] =  "%4i-%02i" % (cc.expire_year, cc.expire_month)
        
        translist = []
        # remove        
        for subscription in subscriptions:
            lineitem = subscription.lineitem

            subtrans = trans.copy()
            subtrans['subscription'] = subscription
            subtrans['product'] = lineitem.name

            if subscription.trial:
                trial_amount = lineitem.total
                trial_tax = lineitem.tax
                trial_shipping = lineitem.shipping
                amount = subscription.recurring_price()
                trial_occurrences = subscription.trial_times                
            else:
                trial_occurrences = 0
                trial_amount = Decimal('0.00')
                amount = subscription.recurring_price

            occurrences = subscription.recurring_times + subscription.trial_times
            if occurrences > 9999:
                occurrences = 9999

            subtrans['occurrences'] = subscription.recurring_times
            subtrans['trial_amount'] = subscription.trial_price
            subtrans['trial_occurrences'] = trial_occurrences
            subtrans['amount'] = trunc_decimal(amount, 2)
            if amount > Decimal('0.00'):
                charged_today = trial_amount
            else:
                charged_today = amount
            
            charged_today = trunc_decimal(charged_today, 2)
                
            subtrans['charged_today'] = charged_today
            translist.append(subtrans)
            
        return translist