Trình thanh tốn với Paypal từ website thương mại

Một phần của tài liệu Tìm hiểu và xây dựng ứng dụng web siêu thị trực tuyến với ASP NET MVC (Trang 40 - 79)

CHƯƠNG 3 : PHÂN TÍCH THIẾT KẾ ỨNG DỤNG

Q trình thanh tốn với Paypal từ website thương mại

Thuộc tính Mơ tả

cmd Cho biết ta đang sử dụng trang paypal ở chế độ gì. Ví dụ như khi cmd có giá trị _xclick tức là ta đang sử dụng Paypal ở chế độ thanh toán (Pay now) . Như vậy trong hệ thống siêu thị trực tuyến này với chức năng checkout ta sẽ gán giá trị _xclick cho tham số cmd của checkout

upload Với giá trị là 1 cho tham số upload cho biết ta sử dụng giỏ hàng của hệ thống chứ khơng dùng giỏ hàng tích hợp của Paypal

business Địa chỉ thư xác định tài khoản business với Paypal của ta. Đây chính là tài khoản dùng để nhận thanh tốn từ giao dịch của khách hàng. Với hệ thống tài khoản này là :

dangti_1273804062_biz@yahoo.com

item_name Đây là chuỗi mô tả đơn đặt hàng mà khách hàng sẽ thanh tốn ví dụ như Oder #01

item_number Con số hay chuỗi số xác định cho một đơn đặt hàng

amount Số tiền mà khách hàng phải trả theo tiền của một nước nào đó được chỉ định bằng mã tiền (currency_code) , định dạng tiền phải ở dạng như sau 33.88

Việc tích hợp thanh tốn với Paypay cho hệ thống siêu thị trực tuyến là không quá phức tạp chỉ cần tạo ra một form HTML với các tham số tương ứng và điều hướng khách hàng từ website thương mại tới trang thanh toán với paypal.

<form id="Paypal" name="Paypal" action="<%=

GlobalStoreSection.Current.Commerce.PayPalServer %>" method="post"> <input type="hidden" name="cmd" value="_cart" />

<input type="hidden" name="upload" value="1" /> <input type="hidden" name="business" value="<%=

GlobalStoreSection.Current.Commerce.PayPalAccount %>" /> <input type="hidden" name="shipping" value="<%=

ViewData.Model.ShippingPrice.ToString("N2") %>" />

<input type="hidden" name="amount" value="<%= ViewData.Model.Total.ToString("N2") %>" />

<% int count = 1; %>

<% foreach(ShoppingCartItem shoppingCartItem in ViewData.Model) { %>

<%=Html.Hidden("amount_" + count, shoppingCartItem.SalePrice.ToString("N2"))%> <%=Html.Hidden("item_name_" + count, shoppingCartItem.Title) %>

<%=Html.Hidden("item_number_" + count, shoppingCartItem.Product.ProductID) %> <%=Html.Hidden("quantity_" + count, shoppingCartItem.Quantity) %>

<%count++;%> <% } %>

<button type="submit" id="paypal-checkout-button" value="PayPal" >Checkout</button> </form>

3.4. Các bảng dữ liệu của module

Module thương mại có tất cả 5 bảng sản phẩm, bảng gian hàng (Deparments) , bảng phương thức vận chuyển (ShippingMethods), bảng đơn đặt hàng (Oders), bảng các mặt hàng trong đơn đặt hàng (OderItems) .

Trong đó quan hệ giữa 2 bảng gian hàng và sản phẩm được thiết lập thơng qua khóa ngoại là DepartmentID với updates và deletes là kiểu do đó khi xóa một gian hàng thì các sản phẩm có trong gian hàng cũng bị xóa.

Tương tự thì có mối quan hệ giữa bảng đơn đặt hàng và bảng các mặt hàng trong đơn đặt hàng được thiết lập bởi khóa ngoại là OderID với updates và delete cũng là kiểu cascade.

Hình 3.8 Sơ đồ quan hệ các bảng dữ liệu trong module thương mại

3.5. Lớp thiết lập cấu hình cho module thương mại

Lớp CommerceElement này dùng thiết lập các cấu hình thanh tốn với Paypal được sử dụng để tạo các thuộc tính sau cho việc thanh tốn

Thuộc tính Mơ tả

PayPalServer Đây chính là máy chủ Paypal mà khách hàng gửi yêu cầu tới đó có thể là máy chủ Sandbox dành cho thử nghiệm có địa chỉ (https://www.sandbox.paypal.com/cgi-bin/webscr) hoặc là máy chủ thực (https://www.paypal.com/cgi-bin/webscr) PayPalAccount Đây là ID của PayPal của k hoặc là một địa chỉ thư điện tử

tương ứng với tài khoản PayPal. Thư điện tử này cần được xác nhận lại với PayPal trước khi có thể dùng đại diện cho tài khoản đó

PayPalIdentityToken Đây là thẻ token được PayPal sử dụng để xác nhận một tài khoản nào đó. Nó có thể có được thơng qua site của Paypal ở mục các tùy chọn trong tài khoản PayPal

Vì lí do bảo mật thì token này khơng được gửi tới chủ tài khoản PayPal tuy nhiên khi chủ tài khoản sử dụng Token này thì nó sẽ xuất hiện ở phía dưới các nút bật tắt kiểu radio của phần truyền dữ liệu thanh toán trên trang tùy chọn phương thức thanh toán.

3.6. Model

Model của module này được chia làm 2 phần . Phần thứ 1 là các lớp thực thể LINQ-to-SQL được tạo tự động từ năm bảng DL trên.

Phương thức hành động Bảo mật Các tham số

Index ---- ----

ViewDepartment ---- int departmentId

ViewProduct ---- int productId

ViewShoppingCart ---- int? shippingMethod

AddShoppingCartItem ---- int productId, int? quantity

DeleteShoppingCartItem ---- int id

CompleteOder ---- string tx, decimal amt

ShoppingSummary ---- ----

ManageStore StoreKeeper ----

ManageDepartment StoreKeeper ----

CreateDepartment StoreKeeper ----

CreateDepartment_OnPost StoreKeeper string title, string imageUrl, string description, int? important

EditDepartment StoreKeeper int departmentId

EditDepartment_OnPost StoreKeeper int id, string title, string imageUrl, string description, int? important

DeleteDepartment StoreKeeper int id

ManageProduct StoreKeeper int id

CreateProduct StoreKeeper int id

CreateProduct_OnPost StoreKeeper int? departmentId, string title, string Phần thứ 2 là các lớp thực thể ta xây dựng thêm hỗ trợ cho việc thực hiện một số chức năng của module ví dụ như phần chức năng với giỏ hàng. Lớp ShoppingCart được sử dụng bởi lớp trừu tượng Profile nhằm duy trì trạng thái giỏ hàng của một người dùng ngay cả khi người dùng này thốt khỏi hệ thống.

Ngồi ra cịn có lớp ShoppingCartItem và lớp tĩnh CommerceQueries chứa các phương thức mở rộng cho lớp Department, Products, và ShippingMethods

Hình 3.10 – Các lớp xây dựng thêm hỗ trợ cho module

3.7. Controller

Lớp controller xử lí tồn bộ các logic nghiệp vụ ứng với các use case của module và chứa các phương thức hành động như sau

Tên trang Đặc tả Đường dẫn ảo

Index.aspx Trang này hiển thị

các gian hàng và đóng vai trị là cổng dành cho việc duyệt các sản phẩm store

ViewDepartment.aspx Trang này được dùng để hiển thị tất cả các sản phẩm trong một gian hàng

store/deparments/{deparmentId}

ViewProduct.aspx Trang này dùng hiển thị một sản phẩm

store/product/{productId}

ViewShoppingCart.aspx Trang này ngoài việc hiển thị chi tiết việc mua hàng của khách hàng thì nó cịn cung cấp một số chức năng như xóa mặt hàng,

store/cart

description, string sku, decimal? unit Price, int? discountPercentage, int? untisInStock, string smallImageUrl, string fullImageUrl

EditProduct StoreKeeper int productId

EditProduct_OnPost StoreKeeper int? departmentId, string title, string description, string sku, decimal? unit Price, int? discountPercentage, int? untisInStock, string smallImageUrl, string fullImageUrl

DeleteProduct StoreKeeper int id

ManageOders StoreKeeper int id

OderDetails StoreKeeper int id, string trackingId

ManageShipping StoreKeeper int id, string trackingId CreateShipping StoreKeeper string title, decimal price

DeleteShipping StoreKeeper int id

3.8. View

Đây là một trong số các module có nhiều view nhất trong hệ thống . Gồm có các view dành cho người dùng với vai trị StoreKeeper và các view dành cho người dùng với các vai trò còn lại. Đây là danh sách các view của module

hàng đã hồn tất việc thanh tốn qua PayPal

TransactionError.aspx Trong trường hợp có lỗi xảy ra trong q trình giao dịch

Trang này khơng chứa đường dẫn ảo . Đường dẫn được định nghĩa bởi hệ thống sẽ được sử dụng để đưa ra thông báo lỗi

ManageStore.aspx Trang này hiển thị tất cả các mục trong module cần được quản lí bởi storekeeper

storekeeper/store

ManageDepartment.aspx Trang này hiển thị tất cả các gian hàng mà storekeeper tạo ra , cho phép storekeeper này có thể xóa, hay thực hiện những thay đổi storekeeper/store/departments

CreateDeparment.aspx Trang này cho phép storekeeper tạo mới gian hàng và thay đổi lại thông tin về gian hàng

storekeeper/store/departments/create storekeeper/store/departments/edit/ {departmentId}

ManageProducts.aspx Trang này

storekeeper dùng để thêm sản phẩm mới, thay đổi lại thơng tin sản phẩm hiện có

storekeeper/store/products/create storekeeper/store/products/edit/ {productId}

MangeOder.aspx Trang này liệt kê tất cả các đơn đặt hàng của hệ thống

storekeeper/store/oders

OderDetail.aspx Trang này cho

phép storekeeper xem chi tiết của đơn đặt hàng

storekeeper/store/oders/{oderId}

ManageShipping.aspx Trang này hiển thị tất cả các tùy chọn trong phương thức vận chuyển và cho phép storekeeper thêm mới hay xóa phương thức vận chuyển

3.9. Sử dụng JavaScript

Mã lệnh javascript xử lí các sự kiện bất đồng bộ dành cho module này nằm trong các tệp commerece.js , manage-product.js, manage-deparment.js

manage-department.js được sử dụng để đảm bảo các trường trong form quản lí gian hàng có được sinh ra như u cầu hay không:

$("#title").focus(function () { ShowMessage(this, "Enter the title for your

department."); });

$("#importance").focus(function() { ShowMessage(this, "(optional) Enter the order of

importance that you want the departments shown in."); });

$("#imageUrl").focus(function() { ShowMessage(this, "The relative web path of an

image you want to be shown with products in this department."); });

$("#description").focus(function() { ShowMessage(this, "Enter a short description of

the department to display to your users."); });

function ValidateTitle() {

return VerifyRequiredField("#title", "required"); }

function ValidateImageUrl() {

return VerifyRequiredField("#imageUrl", "required"); }

function ValidateDescription() {

return VerifyRequiredField("#description", "required"); }

function ValidateDepartment() { var validTitle = ValidateTitle(); var validImage = ValidateImageUrl();

var validDescription = ValidateDescription();

return validTitle && validImage && validDescription; }

$("form.department-create").validate(ValidateDepartment);

Tương tự thì tệp manage-product được sử dụng để đảm bảo các trường thông tin trong form tạo sản phẩm được điền vào đúng theo yêu cầu ..

/*********************************************************************************** * Product

***********************************************************************************/

$("#title").focus(function() { ShowMessage(this, "Enter your product name here."); });

$("#sku").focus(function() { ShowMessage(this, "Enter your SKU number here."); }); $("#unitPrice").focus(function() { ShowMessage(this, "Enter the unit price of this

product."); });

$("#discountPercentage").focus(function() { ShowMessage(this, "Enter the percent off

function ValidateTitle() {

return VerifyRequiredField("#title", "required"); }

function ValidateDescription() {

return VerifyRequiredField("#description", "required"); } function ValidateProduct() { return ValidateTitle() && ValidateDescription(); } $("form.product-create").validate(ValidateProduct); /*********************************************************************************** * Rich Text Editor

***********************************************************************************/

var bodyEditor;

$(document).ready(function() {

bodyEditor = new tinymce.Editor("description", __editorConfig); bodyEditor.onChange.add(function(ed) { bodyEditor.save(); });

bodyEditor.onClick.add(function(ed) { ShowMessage("#description", "Enter the

description of your product here."); });

bodyEditor.render(); });

// clears the message from the description when another input gets focus

$(":input")

.focus(function() { HideMessage("#description"); }) .blur(function() { HideMessage("#description"); });

Trong tệp commerece.js có các đoạn mã lệnh cho cả quản lí gian hàng, quản lí sản phẩm ,…

Đoạn code thực hiện xóa gian hàng khơng tạo ra việc Post back toàn bộ: $(".delete-department-button").click(function() {

var departmentId = $(this).attr("meta:id"); $.post( "/Commerce/DeleteDepartment", { id: departmentId }, function(data) { $("#department-" + data.object.id).remove(); $("#admin-" + data.object.id).remove(); $("#spacer-" + data.object.id).remove(); }, "json" ); return false; });

Đoạn code thực hiện việc xóa sản phẩm khỏi gian hàng khơng tạo ra việc postback toàn bộ:

$(".delete-product-button").click(function () { var productID = $(this).attr("meta:id"); $.post(

"/Commerce/DeleteProduct", { id: productID }, function (data) { $("#product-" + data.object.id).remove(); $("#admin-" + data.object.id).remove(); $("#spacer-" + data.object.id).remove(); }, "json" ); return false; });

Đoạn code thực hiện việc các phương thức ứng với cách thức vận chuyển (như xóa cách thức vận chuyển, thêm cách thức vận chuyển ..) mà không tạo ra Post back toàn bộ:

$(".delete-shipping-method-button").live("click", function() { var shippingMethodId = $(this).attr("meta:id");

$.post( "/Commerce/DeleteShipping", { id: shippingMethodId }, function(data) { $("#shipping-method-" + data.object.id).remove(); }, "json" ); return false; }); $("#add-shipping-method-button").click(function() { var title = $("#title").val();

var price = $("#price").val(); $.post(

"/Commerce/CreateShipping",

{ title: title, price: price }, function(data) {

var html = '<tr id="shipping-method-' + data.object.id + '">'; html += '<td align="center">' + title + '</td>';

html += '<td align="center">' + price + '</td>';

html += '<td align="center"><a href="#" class="delete-shipping-

method-button" meta:id="' + data.object.id + '"><img border="0" alt="Delete Role" src="/content/images/DeleteSymbol.png" title="Delete Role"

align="middle"/></a></td>'; html += '</tr>'; $("#shipping-table tbody").append(html); $("#title").val(""); $("#price").val(""); }, "json" ); return false; });

{ id: productId }, function (data) {

$("#item-" + data.object.id).remove();

//Reload whole page

location.reload(form); }, "json" ); return false; }); 3.10. Cấu hình định tuyến

Định tuyến dành cho các view của người dùng có vai trị là storekeeper: routes.MapRoute(

"CommerceManageStore", "storekeeper/store",

new { controller = "Commerce", action = "ManageStore" } );

routes.MapRoute(

"CommerceManageDepartments", "storekeeper/store/departments",

new { controller = "Commerce", action = "ManageDepartments" } );

routes.MapRoute(

"CommerceCreateDepartment",

"storekeeper/store/departments/create",

new { controller = "Commerce", action = "CreateDepartment" } );

routes.MapRoute(

"CommerceEditDepartment",

"storekeeper/store/departments/edit/{departmentId}",

new { controller = "Commerce", action = "EditDepartment", departmentId = (int?)null }

);

routes.MapRoute(

"CommerceManageProducts", "storekeeper/store/products",

new { controller = "Commerce", action = "ManageProducts" } );

routes.MapRoute(

"CommerceCreateProduct",

"storekeeper/store/products/create",

new { controller = "Commerce", action = "CreateProduct" } );

routes.MapRoute(

"CommerceEditProduct",

"storekeeper/store/products/edit/{productId}",

new { controller = "Commerce", action = "EditProduct", productId = (int?)null }

);

routes.MapRoute(

"CommerceManageOrders", "storekeeper/store/orders",

new { controller = "Commerce", action = "ManageOrders" } );

routes.MapRoute(

"CommerceOrderDetail",

"storekeeper/store/orders/{orderId}",

new { controller = "Commerce", action = "OrderDetail", orderId = (int?)null }

);

routes.MapRoute(

"CommerceManageShipping", "storekeeper/store/shipping",

new { controller = "Commerce", action = "ManageShipping" } );

Định tuyến dành cho những người dùng còn lại: routes.MapRoute(

"CommerceIndex", "",

new { controller = "Commerce", action = "Index" } );

routes.MapRoute(

"CommerceDepartment",

"store/departments/{departmentId}",

new { controller = "Commerce", action = "ViewDepartment", departmentId = (int?)null }

);

routes.MapRoute(

"CommerceProduct",

"store/products/{productId}",

new { controller = "Commerce", action = "ViewProduct", productId = (int?)null }

);

routes.MapRoute(

"CommerceCart", "store/cart",

new { controller = "Commerce", action = "ViewShoppingCart" } );

routes.MapRoute(

"CommerceCompleted", "store/order/completed",

new { controller = "Commerce", action = "CompleteOrder" } );

4. MODULE GỬI THƯ 4.1. Tổng quan về module

Hệ thống ln có những nội dung cập nhật mới như bài báo , diễn đàn, thông tin sản phẩm mới … để tạo sự chú ý cho những người dùng là khách hàng thì hệ thống có module gửi thư thơng báo khách hàng biết có những thơng tin mới đó để rồi khách hàng sẽ quay trở lại sử dụng hệ thống trong trường hợp khách hàng đăng kí nhận thư từ hệ thống.

4.2. Các vấn đề cần quan tâm khi xây dựng module:

Để lưu trữ thơng tin đăng kí nhận thư của người dùng ta chỉ cần lưu các thông tin như địa chỉ thư điện tử của người dùng, tên, họ, định dạng thư nhận. Tất cả các thơng tin này có trong các bảng của module hồ sơ và thành viên ta hồn tồn có thể tận dụng.

Việc tạo và gửi thư điện tử của người dùng với vai trị là nhà quản trị có thể được xây dựng sử dụng namespace System.Net.Mail (namespace này được định nghĩa trong thư viện System.dll) . Các lớp chính cho việc tạo và gửi thư là lớp

MailMessage, và lớp SmtpClient cung cấp các phương thức tạo và gửi thư bằng việc kết nối với máy chủ SMTP đã được cấu hình.

Với lớp MailMessage ta có thể tạo tồn bộ thơng tin đầy đủ của một thư điện tử như sau:

// create the message

MailMessage mail = new MailMessage(); // set the sender's address and display name

mail.From = new MailAddress("dangtienloc@gmail.com", "Loc Dang"); // add a first recipient by specifying only her address

mail.To.Add("doangquangminh@gmail.com");

// add a second recipient by specifying his address and display name

mail.To.Add(new MailAddress("nguyenducdan@gmail.com", "Dan nguyen")); // add a third recipient, but to the CC field this time

mail.CC.Add("mainga@gmail.com"); // set the mail's subject and HTML body mail.Subject = "Sample Mail";

mail.Body = "Hello, <b>my friend</b>!<br />How are you?"; mail.IsBodyHtml = true;

// set the mail’s priority to high mail.Priority = MailPriority.High; // add a couple of attachments mail.Attachments.Add(

new Attachment(@"c:\demo.zip", MediaTypeNames.Application.Octet)); mail.Attachments.Add(

Khi đối tượng MailMessage đã được tạo ta có thể gửi nó bằng phương thức Send của lớp SmtpClient.

SmtpClient smtpClient = new SmtpClient(); smtpClient.Send(mail);

Trước khi có thể gọi phương thức Send ta cần thiết lập các thơng tin cấu hình cho hệ thống để phương thức này có thể thực hiện được như địa chỉ của máy chủ SMTP (thuộc tính SmtpClient Host) , cổng (thuộc tính port) và giấy chứng thực của máy chủ này (thuộc tính credentials) , kết nối được mã hóa với SSL (thuộc tính EnableSsl) và thời gian duy trì từ lúc bắt đầu cho tới khi kết thúc của việc gửi thư ( thuộc tính TimeOut , giá trị mặc định là 100 giây) . Một thuộc tính quan trọng là DeliveryMethod (đây là thuộc tính liệt kê của kiểu dữ liệu SmtpDeliveryMethod. Nó có thể nhận một trong các giá trị sau:

Network: Thư được gửi thông qua kết nối trực tiếp tới một máy chủ Smtp cụ thể PickupDirectoryFromIs: Thư điện tử này được chuẩn bị và tệp thư này được lưu

vào thư mục mặc định là <drive>:\Inetpub\mailroot\Queue. IIS sẽ lấy thư này từ hàng đợi thư để gửi.

SpecifedPickupDirectory: Các tệp EML với thư điện tử sẽ được gửi được lưu

vào thư mục được chỉ định cho thuộc tính này của đối tượng SmtpClient. Thiết lập này sẽ hữu ích khi ta có một ứng dụng ngồi (khơng phải IIS) xử lí việc chọn thư và gửi

Cấu hình phần gửi thư của hệ thống thương mại trực tuyến <system.net>

<mailSettings>

<smtp deliveryMethod="Network" from="dangtienloc@gmail.com">

<network defaultCredentials="true" host="MailServer" port="25"/> </smtp>

</mailSettings> </system.net>

Vấn đề thời gian trong xử lí gửi thư có thể là rất lâu khiến người dùng có thể nghĩ hệ thống có lỗi. Việc gửi thư tới hàng ngàn khách hàng đăng kí nhận thư

(subscribers) thường phải mất hàng phút trong khi để xử lí một yêu cầu theo tiêu chuẩn chỉ nên trong vài giây.

Một giải pháp được đưa ra trong hệ thống đó là khi người dùng nhấn nút submit (tương đương với hành động gửi thư) thì ở phía máy chủ sẽ sinh ra một tiến trình xử lí nhiệm vụ gửi thư mất nhiều thời gian đó ở chế độ nền (backgroudn running mode) và chuyển hướng người dùng về trang quản lí thư . Và ở trang đó người dùng có thể thấy được trạng thái của tất cả các thư đã gửi trong đó có cả thư mới tạo gần nhất và đang được gửi .

Một phần của tài liệu Tìm hiểu và xây dựng ứng dụng web siêu thị trực tuyến với ASP NET MVC (Trang 40 - 79)

Tải bản đầy đủ (DOC)

(122 trang)
w