【从实作学习ASP.NET Core】Day27 | 前台 | PayPal 订单付款 (2)

接续昨天的付款按钮,今天要把自己的订单内容和付款按钮结合


PayPal 订单内容

范例

这边提供一个从别人 issue 里面抄来的测试档,确定是可行的,可以先拿来测试

purchase_units: [{
    amount: {
        value: '7',
        currency_code: 'USD',
        breakdown: {
            item_total: {value: '7', currency_code: 'USD'} //订单金额
        }
    },
    invoice_id: 'muesli_invoice_id',
    items: [{                                              //商品项目
        name: 'Hafer',
        unit_amount: {value: '3', currency_code: 'USD'},
        quantity: '1',
        sku: 'haf001'
    }, {
        name: 'Discount',
        unit_amount: {value: '4', currency_code: 'USD'},
        quantity: '1',
        sku: 'dsc002'
    }]
}]

比照着个形式把订单资料喂给 PayPal 的相对位置
PS. 即使是测试的时候也要注意订单金额和所有商品的总额一定要一致,不然会 Error 喔

<script>
    paypal.Buttons({
        style: {
            shape: 'rect',
            size: 'small',
        },
        createOrder: function (data, actions) {
            return actions.order.create({
                purchase_units: [{
                    amount: {
                        value: @Model.Total,
                        currency_code: 'TWD',
                        breakdown: {
                            item_total: { value: @Model.Total, 
                                          currency_code: 'TWD' }
                        }
                    },
                    items: [
                        @foreach (var item in ViewBag.orderItems)
                        {
                            @:{ name:'@item.Product.Name', 
                                unit_amount: { value:@item.SubTotal, 
                                               currency_code: 'TWD' }, 
                                quantity:@item.Amount },
                        }
                    ]
                }]
            });
        },
        //付款成功後重导向
        onApprove: function (data, actions) {
            return actions.order.capture().then(function (details) {
                console.log(details),
                window.location.
                    replace("/order/payment/[email protected]&isSuccess=true");
            })
        },
        //付款取消後重导向
        onCancel: function (data) {
            window.location.
                replace("/order/payment/[email protected]&isSussess=false");
        }
    }).render('#payment-button')
</script>

执行看看效果如何

阿咧 奇怪怎麽中文字都变成乱码了!?

这个问题是出在 ASP.NET Core 的 TagHelper 及 HtmlHelper 预设会将所有非拉丁字元都当成特殊符号进行编码。要解决这个问题需要将编码器的范围做调整,需要在Startup.cs加入下面的设定来排除中文的编码设定( 参考官方说明文件 )

//自订编码器
services.AddSingleton<HtmlEncoder>(
    HtmlEncoder.Create(allowedRanges: new[] { 
        UnicodeRanges.BasicLatin, UnicodeRanges.CjkUnifiedIdeographs }));

重新执行一次,显示就恢复正常了


订单付款

在页面上点选 PAY NOW 付款就已经成立了,接下来我们只需要把资料库的订单状况改为 已付款 即可

public async Task<IActionResult> Payment(int? Id, bool isSuccess)
{
    if (Id == null)
    {
        return NotFound();
    }

    var order = await _context.Order.FirstOrDefaultAsync(p => p.Id == Id);
    if(order == null)
    {
        return NotFound();
    }
    else
    {
        if (isSuccess)
        {
            order.isPaid = true;
            _context.Update(order);
            await _context.SaveChangesAsync();  //更新订单状态
        }
        return RedirectToAction("ReviewOrder", new { Id = order.Id });
    }
}

想要确认付款也可以到 PayPal Sandox 登入 测试用商业帐号 查看订单,不要登入错了
在下图红框处就能看到我们刚刚那笔付款成立罗

以上就是 PayPal Client-Side Checkout 的简单做法,但其实这样的方式在与资料库的连接逻辑上不太连贯,这个相当於店员手开一张收据给付款人,再到电脑里调整资料,无法保证之间完全不会有出错和漏洞发生。
对於这种有配合资料库系统的专案可能用 Sever-Side 会比较好,这会需要用到 PayPal REST API 但因为时间关系没办法研究太深,以後有机会再回来补充。


<<:  Day 25 - WooCommerce: 验收永丰银行刷卡流程

>>:  Day 24 - Single Number

[VSCodeVim] Vim的思维、哲学与解决问题之道

Vim的思维、哲学与解决问题之道 [系列文目录] 每种工具都有它的设计理念,在接触Vim的前後,我们...

前端工程学习日记第18天-Emmet简易教学 - 快速上手包

资料来源:https://pjchender.blogspot.com/2016/07/emmet....

Day19:SwiftUI—Button

前言 今天来学习SwiftUI 的按钮 — Button。 实作 宣告一个 text 按钮 打开一个...

职位描述 (job description)

职位描述是职位设计的输出之一,它考虑了“分工”的原则,需要人力资源部和研发部进行协作。职位描述是确定...

建立第一个RESTful api server(实作篇)-2(Day14)

在上一步我们建立了一个基础的echo的server 紧接着我们就要建立第一个crud的api了 关於...