def get_dragonpay_token(account_id, checkout_id, email, amount, param1=None): ''' @description: - abstracts dragonpay API implementation - uses dragonpay util to return dragon pay token id ''' # logger scart_logger = sms_api_logger.SCartLogger() # generates a unique transaction id txn_id = DRAGONPAY_TXN_PREFIX %str(checkout_id) description = 'CHIKKA API' scart_logger.info('dragon pay API soap call', { 'user_id': account_id, 'txn_id': txn_id, 'amount': amount, 'email': email}) try: return get_token_via_soap(txn_id=txn_id, amount=amount, email=email, description=description, param1=param1)[0] except Exception, e: scart_logger.error('dragonpay error', { 'user_id': account_id, 'txn_id': txn_id, 'amount': amount, 'email': email, 'error': str(e)}) raise Exception('get dragonpay token failed')
def process_dragonpay_checkout(account_id, amount): ''' @description: - processes checkout for dragonpay @param account_id: account id of user @param txn_id: ''' # before doing anything, double check if # amount is within minimum amount if dp_is_allowed_for_amount(amount): scart_logger = sms_api_logger.SCartLogger() # --- saves checkout to DB and deletes in cache --- # some fields are not necessary for dragonpay checkout checkout_id = __save_cart_items_from_cache_to_db( account_id=account_id, phone='', code='', amount=amount, mode_of_payment='DRAGONPAY', status='PENDING') wipe_out_cached_cart(account_id) return checkout_id else: raise Exception('amount %s is not allowed for dragonpay' % amount)
def process_paymaya_checkout(account_id, amount): ''' @authr: sarz - makmakulet ;) @description: generates checkout record paymaya as mode of payment @param account_id: account id of user @param txn_id: ''' scart_logger = sms_api_logger.SCartLogger() # --- saves checkout to DB and deletes in cache --- checkout_id = __save_cart_items_from_cache_to_db(account_id=account_id, phone='', code='', amount=amount, mode_of_payment='PAYMAYA', status='PENDING') if checkout_id: ########################## # write purchase history ########################## # @todo make a cheaper way to get the checkout object checkout_object = Checkout.get(checkout_id=checkout_id) checkout_object.write_to_purchase_history() # wipe_out_cached_cart(account_id) return checkout_id else: raise ShoppingCartError( 'no checkout generated, shopping cart might be empty')
def delete_from_cart(account_id, plan_id): ''' @description: - adds @param new_data to user's cart ''' scart_logger = sms_api_logger.SCartLogger() # scart_logger.info('START -- deleting item in cart', {'account_id' : account_id}) cached_cart = CachedCart.get_items(account_id) or [] existing_index = None if cached_cart: for i, v in enumerate(cached_cart): if int(v['id']) == int(plan_id): existing_index = i # deletes the item from cart where id == plan_id if existing_index is not None: # 0 is treated as not scart_logger.info('deleting cart item with ID', { 'account_id': account_id, 'item_id': plan_id }) cached_cart.pop(existing_index) # else: # scart_logger.info('cart is empty', {'account_id' : account_id}) # deletes the cart item by saving updated cart CachedCart.save_item_to_cart(account_id, cached_cart) return cached_cart
def save_checkout_items(self, cart_dict): ''' @param cart_item: (dict) ''' if not cart_dict: return None scart_logger = sms_api_logger.SCartLogger() params = { 'plan_code': cart_dict['plan_code'], 'checkout_id': cart_dict['checkout_id'], 'amount': cart_dict['amount'], # 'days_valid': cart_dict['days_valid'], 'date_created': datetime.now(), 'quantity': cart_dict['quantity'] } try: result = self.dbconn.execute_insert( table_name=TABLE_CHECKOUT_ITEMS, params=params) scart_logger.info('SUCCESS -- saving checkout ITEMS to DB', {'checkout_id': cart_dict['checkout_id']}) return result except Exception, e: scart_logger.error('ERROR -- saving checkout ITEMS to db', { 'checkout_id': cart_dict['checkout_id'], 'error': str(e) }) print e
def wipe_out_cached_cart(account_id): ''' @description: - wipes out the shopping cart with @param account_id ''' scart_logger = sms_api_logger.SCartLogger() scart_logger.info('wiping cart', {'account_id': account_id}) return CachedCart.wipe_out_cart(account_id)
def update_checkout_status_to_pending(self, checkout_id): query_str = "UPDATE checkout SET status='PENDING', date_updated='%s' WHERE status is NULL AND expired=0 AND id=%s" % ( datetime.now(), checkout_id) scart_logger = sms_api_logger.SCartLogger() try: self.dbconn.run_query('update', query_str) scart_logger.info('SUCCESS -- checkout status to PENDING', {'checkout_id': checkout_id}) except Exception, e: scart_logger.error('ERROR -- checkout status to PENDING', { 'checkout_id': checkout_id, 'error': str(e) }) print e
def get_cart_items(account_id): ''' @param account_id: the account id of the user obtained from logging in @description: - returns the cart of the user for viewing purpose ''' scart_logger = sms_api_logger.SCartLogger() # scart_logger.info('obtaining cart items', {'account_id' : account_id}) if not Suffixes.is_user_has_suffix(account_id): # scart_logger.error('user has no suffix', {'account_id' : account_id}) raise NoSuffixException(account_id) cached_cart = CachedCart.get_items(account_id) or [] if not cached_cart: # scart_logger.error('cart is empty', {'account_id' : account_id}) raise CartEmptyException(account_id) # trims the needed details for frontend printing cached_cart_trimmed = [] for c in cached_cart: # to prevent hacking (it sec, package details are injected here) __fill_package_details(c) temp = { 'amount': c['amount'], 'id': c['id'], 'plan_code': c['plan_code'], 'quantity': c['quantity'] } cached_cart_trimmed.append(temp) # scart_logger.info('success obtaining cart', {'account_id' : account_id}) return cached_cart_trimmed
def save_checkout(self, account_id, checkout_dict): phone = ('639%s' % checkout_dict['phone'][-9:]) if checkout_dict['phone'] else '' params = { 'account_id': account_id, 'phone': phone, 'code': checkout_dict['code'], 'amount': checkout_dict['amount'], 'date_expiry': checkout_dict['date_expiry'], 'mode_of_payment': checkout_dict['mode_of_payment'], # 'retry_ctr' : 1, 'date_created': datetime.now(), 'suffix': checkout_dict['suffix'], 'expired': '0' } if 'status' in checkout_dict: params['status'] = checkout_dict['status'] # for dragonpay scart_logger = sms_api_logger.SCartLogger() try: result = self.dbconn.execute_insert(table_name=TABLE_CHECKOUT, params=params) scart_logger.info('SUCCESS -- saving CHECKOUT to DB', {'account_id': account_id}) return result except Exception, e: scart_logger.error('ERROR -- saving CHECKOUT to DB', { 'account_id': account_id, 'error': str(e) }) print e
def update_checkout_expired(self, checkout_id): criteria = {'id': checkout_id} params = {'expired': '1', 'date_updated': datetime.now()} scart_logger = sms_api_logger.SCartLogger() try: result = self.dbconn.execute_update(table_name=TABLE_CHECKOUT, params=params, conditions=criteria) scart_logger.info('SUCCESS -- updating CHECKOUT EXPIRATION', {'checkout_id': checkout_id}) return result except Exception, e: scart_logger.error('ERROR -- updating CHECKOUT EXPIRATION', { 'checkout_id': checkout_id, 'error': str(e) }) print e
def get_token_via_soap(txn_id, amount, email, param1=None, param2=None, description=None, ccy='PHP'): ''' @description: - obtains token id from dragon api using soap call which will be used for identifying the user in dragon api's payment page. @param txn_id: - unique transaction id @param amount: - total amount purchased by user @param email: - email of user @param param1 param2: - optional parameters to be returned to the postback url @param description: - description of transaction @param ccy - currency of the transaction ''' scart_logger = sms_api_logger.SCartLogger() scart_logger.info("get token via soap", {"email":email}) body = """<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <GetTxnToken xmlns="%s"> <merchantId>%s</merchantId> <secretKey>%s</secretKey> <password>%s</password> <txnId>%s</txnId> <merchantTxnId>%s</merchantTxnId> <amount>%.2f</amount> <ccy>%s</ccy> <description>%s</description> <email>%s</email> <param1>%s</param1> </GetTxnToken> </soap:Body> </soap:Envelope> """ %(DC['api_url'], DC['merchant_id'], DC['secret_key'], DC['secret_key'], txn_id, txn_id, amount, ccy, description, email, param1) scart_logger.info("soap body", {"body":repr(body)}) headers = { 'Host': DC['host'], 'Content-Type': 'text/xml; charset=utf-8', 'Content-Length': "%d" % len(body), 'SOAPAction': DC['api_get_token_url'] } scart_logger.info("using dragon pay", {"host":Dragonpay.http_conn.host, "uri":DC['uri'] }) try: http_response = Dragonpay.http_conn.post(DC['uri'], body=body, headers=headers).read() response = __parse_soap_response(http_response) except Exception, e: import traceback print traceback.format_exc() return None
def process_smart_payment_verification(account_id, pincode, checkout_id): ''' @description: - processes the pincode verification based from smart payment. - pushes the succesfful verification to checkout_queue (redis) for payment process ''' scart_logger = sms_api_logger.SCartLogger() # scart_logger.info('START -- checkout cart pincode verification', # {'account_id' : account_id, 'checkout_id': checkout_id, 'code': pincode}) #cart_checkout = Cart.get_checkout(account_id, checkout_id) cart_checkout = Checkout.get(checkout_id=checkout_id) if not cart_checkout: scart_logger.error('SMART payment PINCODE -- cant pay. cart is empty', { 'account_id': account_id, 'checkout_id': checkout_id }) raise CartEmptyException(account_id) """ if cart_checkout.retry_ctr >= MAX_PINCODE_TRIES: raise MaxCodeRetriesException(account_id, pincode) """ if not __is_pincode_correct(cart_checkout.code, pincode): scart_logger.error('SMART payment PINCODE -- incorrect pincode', { 'account_id': account_id, 'checkout_id': checkout_id }) # Cart.incr_retry_ctr(checkout_id) raise IncorrectPincodeException(account_id, pincode) if __is_pincode_expired(cart_checkout.date_expiry): scart_logger.error('SMART payment PINCODE -- expired pincode', { 'account_id': account_id, 'checkout_id': checkout_id }) # sets expired to 1, to avoid date recomputations in future Cart.update_checkout_expired(checkout_id) raise ExpiredPincodeException(account_id, pincode) Cart.update_checkout_status_to_pending(checkout_id) cart_checkout.status = Checkout.STATUS_PENDING was_push_successful = CachedCart.push_to_checkout_queue(checkout_id) # write to purchase history #cart_checkout.write_to_purchase_history() try: cart_checkout.write_pending_purchase_history() except Exception, e: scart_logger.error( 'suppress error in writing purchase history. duplicate record may already exist', {'checkout_id': checkout_id})
def process_smart_payment_authentication(account_id, mobile, amount): ''' @description: - processes smart gateway authentication. Used when the user inputs his/her mobile number for payment. - this function: + generates a random code + transfer the redis cart items to DB + sends the pincode to the user ''' scart_logger = sms_api_logger.SCartLogger() # scart_logger.info('START -- smart payment mobile num authentication', # {'account_id' : account_id, 'mobile': mobile, 'amount': amount}) if not is_mobile_format_valid(mobile): scart_logger.error('SMART payment MOBILE -- invalid mobile', { 'account_id': account_id, 'mobile': mobile }) raise InvalidMobileFormatException(mobile) # format to 63XXXXXXXXXX mobile = '63%s' % mobile[-10:] # is mobile smart ? dt = DetermineCarrier(mobile) if dt.get_carrier() != 'SMART': scart_logger.error('SMART payment MOBILE -- mobile not smart', { 'account_id': account_id, 'mobile': mobile }) raise MobileNotSmartException(account_id, mobile) rand_code = generate_code() # scart_logger.info('generating random code', # {'account_id' : account_id, 'code': rand_code}) checkout_id = __save_cart_items_from_cache_to_db(account_id, mobile, rand_code, amount) wipe_out_cached_cart(account_id) # build lightweight smart payment checkout object to send code via sms checkout_object = SmartPaymentGatewayCheckout() checkout_object.checkout_id = checkout_id checkout_object.code = rand_code checkout_object.phone = mobile message_id = checkout_object.send_payment_PIN_code() scart_logger.info( 'SMART payment MOBILE -- sending pincode to user', { 'account_id': account_id, 'mobile': mobile, 'code': rand_code, 'message_id': message_id }) return checkout_id
def add_update_cart(account_id, new_data, type='system_generated'): ''' @param account_id: the account id of the user obtained from logging in @param new_data: (dict) @param type: (system_generated | user_generated) - if system_generated, quantity will be updated by adding the new quantity to the existing (used when adding to cart) - if user_generated, quantity will be the new quantity (used when user modifies the quantity directly when viewing the cart) @description: - adds @param new_data to user's cart ''' scart_logger = sms_api_logger.SCartLogger() # scart_logger.info('START -- adding/updating cart', {'account_id' : account_id}) cached_cart = CachedCart.get_items(account_id) or [] # if the plan is not yet in the cart if not cached_cart or (not int(new_data['id']) in map( lambda x: int(x['id']), cached_cart)): __fill_package_details(new_data) # fills details for package data if new_data: cached_cart.append(new_data) scart_logger.info( 'adding NEW item to cart', { 'account_id': account_id, 'item_id': new_data['id'], 'plan_code': new_data['plan_code'] }) else: existing_index = None for i, v in enumerate(cached_cart): if v and 'id' in new_data and int(v['id']) == int(new_data['id']): existing_index = i if existing_index is not None: # 0 is treated as not # scart_logger.info('adding quantity to EXISTING item in cart', # {'account_id' : account_id, 'item_id': new_data['id']}) # used when adding to cart if type == 'system_generated': scart_logger.info( 'system generated -- updating EXISTING cart item quantity', { 'account_id': account_id, 'item_id': new_data['id'] }) sum = int(cached_cart[existing_index]['quantity']) + int( new_data['quantity']) cached_cart[existing_index]['quantity'] = sum # used when user is modifying the quantities in view cart elif type == 'user_generated': scart_logger.info( 'user generated -- updating EXISTING cart item quantity', { 'account_id': account_id, 'item_id': new_data['id'] }) cached_cart[existing_index]['quantity'] = int( new_data['quantity']) else: cached_cart.append(new_data) # scart_logger.info('success adding item/updating cart', {'account_id' : account_id}) CachedCart.save_item_to_cart(account_id, cached_cart) return cached_cart
account_id) except Exception, e: raise ShoppingCartError( 'unable to check existing pending paypal payment: %s' % e) if existing_pending_paypal_payment_checkout: raise ShoppingCartError( 'Pending paypal payment exists. please wait 10 minutes to purchase another ' ) #check if amount is allowed for checkout amount_allowed = paypal_main.is_allowed_for_amount(amount=amount) if amount_allowed: scart_logger = sms_api_logger.SCartLogger() # --- saves checkout to DB and deletes in cache --- if paypal_main.is_within_allowed_paypal_purchases( account_id=account_id, amount=amount): checkout_id = __save_cart_items_from_cache_to_db( account_id=account_id, phone='', code='', amount=amount, mode_of_payment='PAYPAL', status='PENDING') if checkout_id: