def get(self, hash, checkout_id): logger = sms_api_logger_tool.PaymentLogger() logger.info('receiving paypal payment') message = 'paypal confirmed' token_str = self.get_argument('token', None) logger.info('using token', token_str) formatted_amount = '' try: checkout_object = receive_paypal_callback( token=token_str, account_id=self.current_user.account_id, checkout_id=checkout_id, hash=hash) formatted_amount = 'P%.2f' % checkout_object.amount except Exception, e: logger.error('error occured during paypal payment', str(e)) self.redirect('/cart')
def on_payment_success_paypal(checkout_id): logger = sms_api_logger.PaymentLogger() logger.info('paypal callback') mycheckout = Checkout.get(checkout_id=checkout_id) __process_on_payment_success(checkout_id=checkout_id, account_id=mycheckout.account_id, good_response=True, l=logger)
def main(self): ''' @description: - encapsulates the whole dragonpay transaction status update process ''' payment_logger = sms_api_logger.PaymentLogger() pending_list = self.select_pending_status() if pending_list: for p in pending_list: # status = self.pool.spawn(self.get_txn_status, checkout_id=p) txn_id = DRAGONPAY_TXN_PREFIX % p['id'] lock_key = 'lock:%s' % str(txn_id) try: timeout = gevent.Timeout(TIMEOUT) timeout.start() if LockCache.lock(key=lock_key): # locks txn to avoid multiple processes return else: status = self.get_txn_status(txn_id) if status and status[0] == 'S': # success, payment_logger.info('dragonpay success', { 'txn_id': txn_id, 'status': status[0] }) on_payment_success_dragonpay(txn_id=txn_id, good_response=True) elif status[0] in ['F', 'V']: # failure, unknown, void payment_logger.info('dragonpay failed', { 'txn_id': txn_id, 'status': status[0] }) on_payment_success_dragonpay(txn_id=txn_id, good_response=False) else: # do nothing as of now # refund, chargeback, authorized pass # -- updates dragonpay status -- self.update_dragonpay_status(txn_id=txn_id, status=status[0]) LockCache.unlock(key=lock_key) except Exception: LockCache.unlock(key=lock_key) finally: timeout.cancel()
def on_payment_success_dragonpay(txn_id, good_response): ''' @description: - handles the dragonpay callback - txn_id is just CHKID_<checkout_id> ''' logger = sms_api_logger.PaymentLogger() logger.info('dragonpay callback') checkout_id = txn_id[6:] # extracts only the checkout_id __process_on_payment_success(checkout_id=checkout_id, account_id=None, good_response=good_response, l=logger)
def on_payment_success(callback_response, checkout_id, account_id): ''' this executes the procedures done after a successful payment has been made this process should not be dependent on payment method ''' l = sms_api_logger.PaymentLogger() # check if the json callback is a successful callbak good_response = response_successful(json_response=callback_response) l.info('payment response', good_response) # if not good_response : # return __process_on_payment_success(checkout_id=checkout_id, account_id=account_id, good_response=good_response, l=l)
def post(self): payment_logger = sms_api_logger.PaymentLogger() payment_logger.info('received payment callback') uri_params_string = self.request.uri.replace('/smart_payment_callback', '') params_dict = {} qs = urlparse( self.request.uri ) payment_logger.info( 'using uri',self.request.uri) callback_response_body = self.request.body payment_logger.info('callback body', callback_response_body) if qs : try : qparams = parse_qs( qs.query ) payment_logger.info('using params', qparams) for key,value in qparams.iteritems() : if key == 'aid' : params_dict['account_id'] = value[0] elif key == 'cid' : params_dict['checkout_id'] = value[0] # process checkout as PAID checkout_payment.on_payment_success( callback_response = callback_response_body, checkout_id=params_dict['checkout_id'], account_id=params_dict['account_id'] ) payment_logger.info( 'payment sequence finalized' ) except Exception, e : payment_logger.error('exception raised while receiving payment callback', e)
def notify_payment_successful(account_object, checkout_object, send_sms=True): ''' this function sends notification to the user regarding successful credit top up for now, email and sms are sent requires a valid account object ''' l = sms_api_logger.PaymentLogger() current_date_formatted = datetime.now().strftime('%b %d, %Y %H:%M') try: amount = float(checkout_object.amount) current_balance = float(credit_tool.get_balance(account_object.suffix)) except: amount = 0 current_balance = 0 l.info( 'sending_notification', { 'amount_paid': checkout_object.amount, 'account id': account_object.account_id, 'checkout id': checkout_object.checkout_id }) l.info('notifying user by email', {'email': account_object.email}) body = prepare_payment_notif_body(amount=amount, current_balance=current_balance) __queue_email_notification(email=account_object.email, body=body) if send_sms: l.info('notifying user via sms', {'phone': checkout_object.phone}) sms_body = '%s This msg is free' % body __send_sms_notif(phone=checkout_object.phone, body=sms_body)
define("local_settings", default="true", help="enable/disable use of local settings", type=str) parse_command_line() Configuration.initialize() values = Configuration.values() import gevent from gevent.pool import Pool import features.payments.checkout as checkout_payment from features.payments.checkout import __process_on_payment_success import features.logging as sms_api_logger l = sms_api_logger.PaymentLogger() checkout_id = 226 account_id = 4 __process_on_payment_success(checkout_id=checkout_id, account_id=account_id, good_response=True, l=l) # checkout_payment.on_payment_success( callback_response = callback_response_body, # checkout_id=params_dict['checkout_id'], # account_id=params_dict['account_id'] )
def post(self): payment_logger = sms_api_logger.PaymentLogger() txn_id = self.get_argument('txnid') refno = self.get_argument('refno') status = self.get_argument('status') message = self.get_argument('message') lock_key = 'lock:%s' % str(txn_id) # --- locking --- if LockCache.lock(key=lock_key): # locks txn to avoid multiple processes return else: # ! you should delete this once URL was already encoded ! # message = message.replace('000', '[000]') digest = self.get_argument('digest') ctoken_id = self.get_argument('param1', None) is_digest_valid = validate_dragonpay_digest(txn_id=txn_id, refno=refno, status=status, message=message, dragonpay_digest=digest, ctoken_id=ctoken_id) if not is_digest_valid: # --- invalid dragonpay digest --- payment_logger.error('DRAGONPAY INVALID DIGEST', {'txn_id': txn_id, 'refno': refno, 'status': status, 'message': message, 'digest': digest, 'ctoken_id': ctoken_id}) LockCache.unlock(key=lock_key) return is_ctoken_valid = Dragonpay.is_ctoken_valid(txn_id=txn_id, ctoken_id=ctoken_id) if not is_ctoken_valid: # --- invalid ctoken digest --- payment_logger.error('DRAGONPAY INVALID CTOKEN', {'txn_id': txn_id, 'refno': refno, 'status': status, 'message': message, 'digest': digest, 'ctoken_id': ctoken_id}) LockCache.unlock(key=lock_key) return # -- updates status in dragonpay table in DB --- try: Dragonpay.update(txn_id=txn_id, refno=refno, status=status, message=message) payment_logger.info('DRAGONPAY SUCCESS UPDATING DB', {'txn_id': txn_id, 'refno': refno, 'status': status, 'message': message, 'digest': digest, 'ctoken_id': ctoken_id}) except Exception, e: payment_logger.error('DRAGONPAY UNABLE TO UPDATE DB', {'txn_id': txn_id, 'refno': refno, 'status': status, 'message': message, 'digest': digest, 'ctoken_id': ctoken_id}) return # -- process callback -- if status in ['R', 'K']: # Refund | Chargeback # ! to be implemented. waiting for business rules ! payment_logger.info('DRAGONPAY STATUS IN [REFUND | CHANGEBACK]', {'txn_id': txn_id, 'refno': refno, 'status': status, 'message': message, 'digest': digest, 'ctoken_id': ctoken_id}) elif status in ['P', 'U']: # pending # unknown's behavior is unpredictable payment_logger.info('DRAGONPAY STATUS IN [PENDING | UNKNOWN]', {'txn_id': txn_id, 'refno': refno, 'status': status, 'message': message, 'digest': digest, 'ctoken_id': ctoken_id}) else: good_response = True if status == 'S' else False # --- update DB and cache; the user paid successfully --- checkout_payment.on_payment_success_dragonpay( txn_id=txn_id, good_response=good_response)
def pay_via_smart_payment(checkout_id): ''' wrapper for paying via smart payment gateway @return: Boolean , payment sucess ''' payment_success = False payment_logger = sms_api_logger.PaymentLogger() payment_logger.info('executing payment via SMART PAYMENT GATEWAY') max_tries = 3 # step 1 load checkout object checkout_object = Checkout.get_for_payment(checkout_id=checkout_id) if checkout_object: payment_logger.info('reference checkout id', checkout_id) callback_params = { 'cid': checkout_object.checkout_id, 'aid': checkout_object.account_id } # step 2 call EJ api and pay amount using checkout data # retry 3 times # log on error # generate transactionid trans_id = '%s:%s' % (checkout_object.checkout_id, ''.join( random.choice('ABCDEFGHJKMNPQRSTUVWXYZ23456789') for x in range(6))) success = False try_run = 1 result = None while success is False and try_run <= max_tries: try: payment_logger.info( 'try %s : sending payment' % try_run, { 'payment_trans_id': trans_id, 'amount': checkout_object.amount, 'callback_params': callback_params }) result = smart_payment.execute_payment( min=checkout_object.phone, amount=checkout_object.amount, trans_id=trans_id, callback_params=callback_params) payment_logger.info('gateway result', result) except Exception, e: payment_logger.error('exception raised while paying: %s' % e, repr(e)) gevent.sleep(1) else: if not result: payment_logger.error('payment FAILED') gevent.sleep(1) else: success = True payment_logger.info('payment successful!!!') payment_success = True finally: