When I check in my website using Paypal it gives me this message: "Checkout Error - Amount total mismatch" I used Microsoft tutorial to implement PayPal:
I did exactly what it said I even did twice but somehow keep getting this error Appreciate your help Thanks
public partial class CheckoutReview : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
NVPAPICaller payPalCaller = new NVPAPICaller();
string retMsg = "";
string token = "";
string PayerID = "";
NVPCodec decoder = new NVPCodec();
token = Session["token"].ToString();
bool ret = payPalCaller.GetCheckoutDetails(token, ref PayerID, ref decoder, ref retMsg);
if (ret)
{
Session["payerId"] = PayerID;
var myOrder = new Order();
myOrder.OrderDate = Convert.ToDateTime(decoder["TIMESTAMP"].ToString());
myOrder.Username = User.Identity.Name;
myOrder.FirstName = decoder["FIRSTNAME"].ToString();
myOrder.LastName = decoder["LASTNAME"].ToString();
myOrder.Address = decoder["SHIPTOSTREET"].ToString();
myOrder.City = decoder["SHIPTOCITY"].ToString();
myOrder.State = decoder["SHIPTOSTATE"].ToString();
myOrder.PostalCode = decoder["SHIPTOZIP"].ToString();
myOrder.Country = decoder["SHIPTOCOUNTRYCODE"].ToString();
myOrder.Email = decoder["EMAIL"].ToString();
myOrder.Total = Convert.ToDecimal(decoder["AMT"].ToString());
// Verify total payment amount as set on CheckoutStart.aspx.
try
{
decimal paymentAmountOnCheckout = Convert.ToDecimal(Session["payment_amt"].ToString());
decimal paymentAmoutFromPayPal = Convert.ToDecimal(decoder["AMT"].ToString());
if (paymentAmountOnCheckout != paymentAmoutFromPayPal)
{
Response.Redirect("CheckoutError.aspx?" + "Desc=Amount%20total%20mismatch.");
}
}
catch (Exception)
{
Response.Redirect("CheckoutError.aspx?" + "Desc=Amount%20total%20mismatch.");
}
// Get DB context.
ProductContext _db = new ProductContext();
// Add order to DB.
_db.Orders.Add(myOrder);
_db.SaveChanges();
// Get the shopping cart items and process them.
using (WingtipToys.Logic.ShoppingCartActions usersShoppingCart = new WingtipToys.Logic.ShoppingCartActions())
{
List<CartItem> myOrderList = usersShoppingCart.GetCartItems();
// Add OrderDetail information to the DB for each product purchased.
for (int i = 0; i < myOrderList.Count; i++)
{
// Create a new OrderDetail object.
var myOrderDetail = new OrderDetail();
myOrderDetail.OrderId = myOrder.OrderId;
myOrderDetail.Username = User.Identity.Name;
myOrderDetail.ProductId = myOrderList[i].ProductId;
myOrderDetail.Quantity = myOrderList[i].Quantity;
myOrderDetail.UnitPrice = myOrderList[i].Product.UnitPrice;
// Add OrderDetail to DB.
_db.OrderDetails.Add(myOrderDetail);
_db.SaveChanges();
}
// Set OrderId.
Session["currentOrderId"] = myOrder.OrderId;
// Display Order information.
List<Order> orderList = new List<Order>();
orderList.Add(myOrder);
ShipInfo.DataSource = orderList;
ShipInfo.DataBind();
// Display OrderDetails.
OrderItemList.DataSource = myOrderList;
OrderItemList.DataBind();
}
}
else
{
Response.Redirect("CheckoutError.aspx?" + retMsg);
}
}
}
protected void CheckoutConfirm_Click(object sender, EventArgs e)
{
Session["userCheckoutCompleted"] = "true";
Response.Redirect("~/Checkout/CheckoutComplete.aspx");
}
}
I encountered the same problem while doing the tutorial, so here is my solution in case someone encounters it as well.
The main problem here is that Asp.NET displays the string versions of the amounts as XX,XX
instead of XX.XX
. This is because the .ToString()
-function displays decimals as they are written in the current region.
To solve this problem, every .ToString()
and Convert.ToDecimal()
should be called with an extra parameter called CultureInfo.InvariantCulture
, which ensures that the string amounts are stored in memory in the XX.XX
-format.
I hope this helps someone in the future.