/// <summary> /// This method is used internally only /// Updates the orders payment amount. I was watching x-files S2E6:Ascension via Netflix instant watch when I wrote it. /// </summary> /// <param name="orderIds">The order ids.</param> /// <param name="amount">The amount to be paid across the selected orders, in sequential until amount param is used up.</param> /// <param name="paymentMethodId">The payment method id.</param> /// <param name="cn">The sql connection (or null).</param> /// <param name="trans">The sql transaction (or null).</param> private static void UpdateOrders( List<object> orderIds, decimal amount, Guid paymentMethodId, SqlConnection cn, SqlTransaction trans ) { List<int> intIds = orderIds.ConvertAll( delegate( object i ) { return Convert.ToInt32( i ); } ); List<Commerce.Order> orders = Commerce.Order.GetOrdersByOrderIds( intIds.ToArray(), cn, trans ); decimal runningTotal = amount; foreach( Commerce.Order order in orders ) { if( amount > 0 ) { decimal amountToPay = order.GrandTotal - order.Paid; if( amount >= amountToPay ) { /* this order has now been paid for */ using( SqlCommand cmd = new SqlCommand( @"update orders set paid = grandTotal where orderId = @orderId; /* add a comment */ insert into objectFlags select newId() as flagId,null as serialId,null as cartDetailId, null as fuserId,null as shipmentId,@orderId as orderId,0 as flagType, 'A payment of '+cast(@amountPaid as varchar(50))+' was made paying this order off.' as comments, 0 as userId, getDate() as addTime, null as VerCol; /* add a reference to this order, and how much of it was paid using this method */ insert into paymentMethodsDetail select newid(),@paymentMethodId,@orderId,@amountPaid", cn, trans ) ) { /* find out what's left to be paid on this order */ runningTotal -= amountToPay;/* subtract the running total */ cmd.Parameters.Add( "@amountPaid", SqlDbType.Money ).Value = amountToPay; cmd.Parameters.Add( "@orderId", SqlDbType.Int ).Value = order.OrderId; cmd.Parameters.Add( "@paymentMethodId", SqlDbType.UniqueIdentifier ).Value = new Guid( paymentMethodId.ToString() ); cmd.ExecuteNonQuery(); } } else { /* this order has been partially paid for */ using( SqlCommand cmd = new SqlCommand( @"update orders set paid = paid + @amountPaid where orderId = @orderId; /* add a comment */ insert into objectFlags select newId() as flagId,null as serialId,null as cartDetailId, null as fuserId,null as shipmentId,@orderId as orderId,0 as flagType, 'A payment of '+cast(@amountPaid as varchar(50))+' was made partially paying for this order.' as comments, 0 as userId, getDate() as addTime, null as VerCol; /* add a reference to this order, and how much of it was paid using this method */ insert into paymentMethodsDetail select newid(),@paymentMethodId,@orderId,@amountPaid", cn, trans ) ) { cmd.Parameters.Add( "@amountPaid", SqlDbType.Money ).Value = amount; cmd.Parameters.Add( "@orderId", SqlDbType.Int ).Value = order.OrderId; cmd.Parameters.Add( "@paymentMethodId", SqlDbType.UniqueIdentifier ).Value = new Guid( paymentMethodId.ToString() ); cmd.ExecuteNonQuery(); runningTotal = 0; } } } } }
/// <summary> /// Pays with a wire transfer. /// </summary> /// <param name="swift">The SWIFT number.</param> /// <param name="bankName">Name of the bank.</param> /// <param name="routingTransitNumber">The routing transit number.</param> /// <param name="amount">The amount.</param> /// <param name="userId">The userId.</param> /// <param name="postingDate">The posting date.</param> /// <param name="orderIds">The order ids.</param> /// <param name="cn">The sql connection (or null).</param> /// <param name="trans">The sql transaction (or null).</param> /// <returns>{error:0,desc:"error description"}.</returns> public static Dictionary<string, object> PayWithWire( string swift, string bankName, string routingTransitNumber, decimal amount, int userId, DateTime postingDate, List<object> orderIds, SqlConnection cn, SqlTransaction trans ) { List<int> intIds = orderIds.ConvertAll( delegate( object i ) { return Convert.ToInt32( i ); } ); Dictionary<string, object> j = new Dictionary<string, object>(); Guid paymentMethodId = Guid.NewGuid(); Commerce.Wire wire = new Commerce.Wire( swift, bankName, routingTransitNumber ); wire.Insert( paymentMethodId, userId, Guid.Empty, -1, "", amount, postingDate, intIds, "", cn, trans ); /* update the orders with the payment data */ UpdateOrders( orderIds, amount, paymentMethodId, cn, trans ); j.Add( "paymentMethodId", paymentMethodId.ToString() ); j.Add( "error", 0 ); j.Add( "description", "" ); return j; }
/// <summary> /// Pays with existing payment. /// </summary> /// <param name="paymentMethodIds">The list of paymentMethodIds.</param> /// <param name="amount">The amount.</param> /// <param name="userId">The userId.</param> /// <param name="postingDate">The posting date.</param> /// <param name="orderIds">The order ids.</param> /// <param name="cn">The sql connection (or null).</param> /// <param name="trans">The sql transaction (or null).</param> /// <returns>{error:0,desc:"error description"}.</returns> public static Dictionary<string, object> PayWithExistingPaymentMethods( List<object> paymentMethodIds, decimal amount, int userId, DateTime postingDate, List<object> orderIds, SqlConnection cn, SqlTransaction trans ) { int errorId = 0; string desc = ""; List<int> intIds = orderIds.ConvertAll( delegate( object i ) { return Convert.ToInt32( i ); } ); Dictionary<string, object> j = new Dictionary<string, object>(); /* before updating - check to ensure that there really is enouch left over on this paymentMethodId(s) * to attach the desiered amount to the selected order */ using( SqlCommand cmd = new SqlCommand() ) { List<SqlDataRecord> rec_paymentMethodIds = new List<SqlDataRecord>(); List<SqlDataRecord> rec_orderIds = new List<SqlDataRecord>(); SqlMetaData[] hashTable = { new SqlMetaData("keyName",SqlDbType.VarChar,100), new SqlMetaData("keyValue",SqlDbType.Variant), new SqlMetaData("primary_key",SqlDbType.Bit), new SqlMetaData("dataType",SqlDbType.VarChar,50), new SqlMetaData("dataLength",SqlDbType.Int), new SqlMetaData("varCharMaxValue",SqlDbType.VarChar,-1) }; foreach( string id in paymentMethodIds ) { SqlDataRecord rec = new SqlDataRecord( hashTable ); rec.SetValue( 0, "paymentMethodId" ); rec.SetValue( 1, id ); rec.SetBoolean( 2, false ); rec.SetString( 3, "uniqueidentifier" ); rec.SetValue( 4, 32 ); rec_paymentMethodIds.Add( rec ); } foreach( int id in intIds ) { SqlDataRecord rec = new SqlDataRecord( hashTable ); rec.SetValue( 0, "orderId" ); rec.SetValue( 1, id ); rec.SetBoolean( 2, false ); rec.SetString( 3, "int" ); rec.SetValue( 4, 8 ); rec_orderIds.Add( rec ); } cmd.Connection = cn; cmd.Transaction = trans; cmd.CommandType = CommandType.StoredProcedure; /* this SP will return a single row with error, desc saying if the procedure was successfull. * the SP sums the remaning total value left on the selected paymentMethods and compares * it to the amount trying to be paid. If the remaining amount is >= the amount trying to * be paid the payments will be attached, if the remaining amount is < the amoun trying to * be paid an error will be returned saying as much. */ cmd.CommandText = "dbo.attachPaymentMethods"; cmd.Parameters.Add( "@amountTryingToBePaid", SqlDbType.Money ).Value = amount; cmd.Parameters.Add( "@paymentMethodIds", SqlDbType.Structured ); cmd.Parameters[ "@paymentMethodIds" ].Direction = ParameterDirection.Input; if( rec_paymentMethodIds.Count == 0 ) { string message = "You must select at least one payment method."; message.Debug( 7 ); Exception ex = new Exception( message ); throw ex; } else { cmd.Parameters[ "@paymentMethodIds" ].Value = rec_paymentMethodIds; } cmd.Parameters.Add( "@orderIds", SqlDbType.Structured ); cmd.Parameters[ "@orderIds" ].Direction = ParameterDirection.Input; if( rec_orderIds.Count == 0 ) { string message = "You must select at least one payment method."; message.Debug( 7 ); Exception ex = new Exception( message ); throw ex; } else { cmd.Parameters[ "@orderIds" ].Value = rec_orderIds; } using( SqlDataReader r = cmd.ExecuteReader() ) { /* batch 1 is the status */ r.Read(); Dictionary<string, object> s = new Dictionary<string, object>(); errorId = r.GetInt32( 0 ); desc = r.GetString( 1 ); /* NOTE: Addtional callback information for attaching payments to orders * I don't really care about this stuff so I'm not going to write anything to capture it * but there is is for anyone who does want to capture it. */ /* batch 2 is the actual payment detail inserts (paymentMethodDetailId,paymentMethodId,refId,amount)*/ /* batch 3 is the actual upated orders (orderId, paid) */ } } if( errorId != 0 ) { j.Add( "error", errorId ); j.Add( "description", desc ); } else { j.Add( "error", 0 ); j.Add( "description", "" ); } return j; }
/// <summary> /// Pays with pay pal. /// </summary> /// <param name="payPalEmailAddress">The pay pal email Address.</param> /// <param name="amount">The amount.</param> /// <param name="userId">The userId.</param> /// <param name="postingDate">The posting date.</param> /// <param name="orderIds">The order ids.</param> /// <param name="cn">The sql connection (or null).</param> /// <param name="trans">The sql transaction (or null).</param> /// <returns>{error:0,desc:"error description"}.</returns> public static Dictionary<string, object> PayWithPayPal( string payPalEmailAddress, decimal amount, int userId, DateTime postingDate, List<object> orderIds, SqlConnection cn, SqlTransaction trans ) { List<int> intIds = orderIds.ConvertAll( delegate( object i ) { return Convert.ToInt32( i ); } ); Dictionary<string, object> j = new Dictionary<string, object>(); Guid paymentMethodId = Guid.NewGuid(); Commerce.PayPal payPal = new Commerce.PayPal( payPalEmailAddress ); payPal.Insert( paymentMethodId, userId, Guid.Empty, -1, "", amount, postingDate, intIds, "", cn, trans ); /* update the orders with the payment data */ UpdateOrders( orderIds, amount, paymentMethodId, cn, trans ); j.Add( "paymentMethodId", paymentMethodId.ToString() ); j.Add( "error", 0 ); j.Add( "description", "" ); return j; }
/// <summary> /// Pays with a credit card. /// </summary> /// <param name="cardName">Name on the card.</param> /// <param name="cardType">Type of card (not used or recorded).</param> /// <param name="cardNumber">The card number.</param> /// <param name="expMonth">The exp month (two digit).</param> /// <param name="expYear">The exp year (two digit).</param> /// <param name="secNumber">The security number.</param> /// <param name="amount">The amount.</param> /// <param name="userId">The userId.</param> /// <param name="postingDate">The posting date.</param> /// <param name="orderIds">The order ids.</param> /// <param name="cn">The sql connection (or null).</param> /// <param name="trans">The sql transaction (or null).</param> /// <returns>{error:0,desc:"error description"}.</returns> public static Dictionary<string, object> PayWithCreditCard( string cardName, string cardType, string cardNumber, string expMonth, string expYear, string secNumber, decimal amount, int userId, DateTime postingDate, List<object> orderIds, SqlConnection cn, SqlTransaction trans ) { List<int> intIds = orderIds.ConvertAll( delegate( object i ) { return Convert.ToInt32( i ); } ); Dictionary<string, object> j = new Dictionary<string, object>(); Guid paymentMethodId = Guid.NewGuid(); int error = 0; string description = ""; Commerce.CreditCard card = new CreditCard( cardType, cardNumber, cardName, secNumber, expMonth, expYear ); Commerce.Order ord = Commerce.Order.GetOrderByOrderId( intIds[ 0 ] ); /* use the first order's bill to and ship to Address to validate the credit card */ Dictionary<string, object> vt = Commerce.VirtualTerminal.ChargeCreditCard( ord.BillToAddress, ord.ShipToAddresses[ 0 ], card, amount, ord.SessionId, ord.OrderNumber + " Group", ord.PurchaseOrder + " Group", cn, trans ); if( vt == null ) { string _msg = "Internal virtual terminal error. Unable to create virtual terminal object."; j.Add( "error", -1754 ); j.Add( "description", _msg ); Exception e = new Exception( _msg ); String.Format( "payWithCreditCard threw an exception ==>{0}", e.Message ).Debug( 3 ); throw e; } error = Convert.ToInt32( vt[ "error" ].ToString() != "0" );/* 1 means error, 0 means no error */ description = vt[ "description" ].ToString(); if( error == 0 ) { /* update orders becuase the transaction was successful this posts the entry to the general ledger table */ card.Insert( paymentMethodId, Guid.Empty, userId, Guid.Empty, -1, "", amount, postingDate, intIds, "", cn, trans ); /* update the orders with the payment data */ UpdateOrders( orderIds, amount, paymentMethodId, cn, trans ); } j.Add( "paymentMethodId", paymentMethodId.ToString() ); j.Add( "error", error ); j.Add( "description", description ); return j; }