搜尋
首頁web前端js教程深入解析:PayPal整合第二部分:PayPal REST API

深入解析:PayPal整合第二部分:PayPal REST API

在本教學中,我將向您展示如何使用 PayPal REST API 和 C# 進行付款。他們針對 Ruby、Node.js、Python、PHP 等不同語言提供的所有函式庫都非常相似,因此這裡的所有概念都適用於所有函式庫。

項目設定

首先,我在 Visual Studio 2015 中建立了一個 MVC 專案:檔案 > 新建 > 專案,然後選擇 ASP.NET 應用程式

深入解析:PayPal整合第二部分:PayPal REST API

選擇 ASP.NET 5 Web 應用程式 模板,該模板使用新的 MVC 6。如果你熟悉的話,它與 MVC 5 類似。

深入解析:PayPal整合第二部分:PayPal REST API

正如您在下面的照片中看到的,我已向解決方案添加了一些文件和資料夾。主要需要注意的兩件事是:

  1. 參考中,我刪除了目標 DNX Core 5.0,它允許我們在 Mac OS X 或 Linux 中運行此項目,但我們需要的 PayPal 庫尚未更新然而。
  2. 我新增了「Services」資料夾,我將在其中封裝 PayPal 呼叫的邏輯,這樣我們就可以保持控制器簡潔明了。

深入解析:PayPal整合第二部分:PayPal REST API

使用 NuGet 安裝 PayPal SDK。 右鍵點擊解決方案名稱並選擇管理 NuGet 套件,然後搜尋「PayPal」並安裝它。

深入解析:PayPal整合第二部分:PayPal REST API

建立 PayPal 應用程式

#要將我們的應用程式與 PayPal 集成,我們需要導航到 PayPal Developers,然後在 REST API 應用程式下,點擊建立應用程式

深入解析:PayPal整合第二部分:PayPal REST API

為您的應用程式命名並選擇與該應用程式關聯的沙盒開發者帳戶。出於測試目的,我們可以導航到 http://sandbox.paypal.com 並使用沙箱登錄詳細資訊進行登錄,以查看測試 PayPal 帳戶和交易。

深入解析:PayPal整合第二部分:PayPal REST API

點擊建立應用程式後,我們會看到包含客戶端 ID 和秘密令牌的確認畫面.

深入解析:PayPal整合第二部分:PayPal REST API

將 clientId 和 clientSecret 令牌複製到 appsettings.json,如螢幕截圖所示如下:

深入解析:PayPal整合第二部分:PayPal REST API

測試付款

PayPal 提供了沙盒環境進行測試。您可以從那裡建立測試買家和賣家帳戶。註冊後,您將在沙盒中擁有一個與您的開發者帳戶綁定的企業帳戶。

要建立新的測試帳戶,請登入開發者網站,然後點擊控制面板標籤並導覽至沙盒 > 帳戶。 您可以在此處查看測試帳戶清單(如果有):

深入解析:PayPal整合第二部分:PayPal REST API

如果您尚未建立測試帳戶,請繼續並點擊建立帳戶在右上角,建立至少一個測試個人帳戶和一個測試企業帳戶。

深入解析:PayPal整合第二部分:PayPal REST API

建立測試帳戶後,您可以使用測試電子郵件地址和密碼透過 www.sandbox.paypal.com 登入您在上一個表格上指派給每個帳戶的資訊。這對於測試當您使用「個人測試帳戶」購買商品時資金是否會轉移到您的「測試企業帳戶」非常有用。現在您已準備好開始與 PayPal 整合並測試資金是否從一個帳戶轉移到另一個帳戶。

單一 PayPal 付款

PayPal 提供不同的付款方式。您可以使用直接信用卡付款,這表示您的客戶無法看到 PayPal 登入頁面或摘要 - 這一切都發生在您的網站上。為此,您需要符合 PCI 標準,我建議使用 Stripe,因為您只需要使用其 JavaScript 程式庫的 SSL。另一方面,要透過 PayPal 付款,需要三個步驟:

  1. 指定付款資訊以建立付款。
  2. 獲得付款批准,將您的客戶重新導向至 PayPal 以批准交易。
  3. 在 PayPal 將您的客戶重新導向回您的網站後,執行付款以獲取資金。

在我的 MVC 專案的 Services 資料夾中,我建立了 PayPalPaymentService 類,並在其中新增了以下方法:

#
public static Payment CreatePayment(string baseUrl, string intent)
{
    // ### Api Context
    // Pass in a `APIContext` object to authenticate 
    // the call and to send a unique request id 
    // (that ensures idempotency). The SDK generates
    // a request id if you do not pass one explicitly. 
    var apiContext = PayPalConfiguration.GetAPIContext();

    // Payment Resource
    var payment = new Payment()
    {
        intent = intent,    // `sale` or `authorize`
        payer = new Payer() { payment_method = "paypal" },
        transactions = GetTransactionsList(),
        redirect_urls = GetReturnUrls(baseUrl, intent)
    };

    // Create a payment using a valid APIContext
    var createdPayment = payment.Create(apiContext);

    return createdPayment;
}

private static List<Transaction> GetTransactionsList()
{
    // A transaction defines the contract of a payment
    // what is the payment for and who is fulfilling it. 
    var transactionList = new List<Transaction>();

    // The Payment creation API requires a list of Transaction; 
    // add the created Transaction to a List
    transactionList.Add(new Transaction()
    {
        description = "Transaction description.",
        invoice_number = GetRandomInvoiceNumber(),
        amount = new Amount()
        {
            currency = "USD",
            total = "100.00",       // Total must be equal to sum of shipping, tax and subtotal.
            details = new Details() // Details: Let's you specify details of a payment amount.
            {
                tax = "15",
                shipping = "10",
                subtotal = "75"
            }
        },
        item_list = new ItemList()
        {
            items = new List<Item>()
            {
                new Item()
                {
                    name = "Item Name",
                    currency = "USD",
                    price = "15",
                    quantity = "5",
                    sku = "sku"
                }
            }
        }
    });
    return transactionList;
}

private static RedirectUrls GetReturnUrls(string baseUrl, string intent)
{
    var returnUrl = intent == "sale" ? "/Home/PaymentSuccessful" : "/Home/AuthorizeSuccessful";

    // Redirect URLS
    // These URLs will determine how the user is redirected from PayPal 
    // once they have either approved or canceled the payment.
    return new RedirectUrls()
    {
        cancel_url = baseUrl + "/Home/PaymentCancelled",
        return_url = baseUrl + returnUrl
    };
}

public static Payment ExecutePayment(string paymentId, string payerId)
{
    // ### Api Context
    // Pass in a `APIContext` object to authenticate 
    // the call and to send a unique request id 
    // (that ensures idempotency). The SDK generates
    // a request id if you do not pass one explicitly. 
    var apiContext = PayPalConfiguration.GetAPIContext();
    
    var paymentExecution = new PaymentExecution() { payer_id = payerId };
    var payment = new Payment() { id = paymentId };

    // Execute the payment.
    var executedPayment = payment.Execute(apiContext, paymentExecution);

    return executedPayment;
}

此呼叫中傳遞了一些參數:

  • 意圖:三個可能的值:「銷售」用於立即付款,「授權」用於授權稍後捕獲付款,或「訂單」用於建立訂單。當您獲得授權稍後收取付款時,您有 3 天的保證期限,不過您最多可以在 29 天後嘗試收取付款。
  • 付款人:此付款的資金來源、所使用的付款方式 - PayPal 電子錢包付款、銀行直接簽帳卡或直接信用卡。
  • 交易:用於指定付款金額,並可選擇指定要支付的項目。如果需要,您也可以指定小計、運費和稅金。
  • 重定向網址:指定 PayPal 在交易後將您的客戶重新導向到的網址,以便您可以更新資料庫並顯示確認訊息。

可以從控制器中使用先前的功能,如下所示:

public IActionResult CreatePayment()
{
    var payment = PayPalPaymentService.CreatePayment(GetBaseUrl(), "sale");
    
    return Redirect(payment.GetApprovalUrl());
}

public IActionResult PaymentCancelled()
{
    // TODO: Handle cancelled payment
    return RedirectToAction("Error");
}

public IActionResult PaymentSuccessful(string paymentId, string token, string PayerID)
{
    // Execute Payment
    var payment = PayPalPaymentService.ExecutePayment(paymentId, PayerID);

    return View();
}

如您所見,我創建了三個操作:

  • CreatePayment:這是觸發付款的動作。它會呼叫 PayPal 以建立付款,然後將使用者重新導向到 PayPal 以批准交易。
  • 付款成功:這是 PayPal 在成功付款後將客戶重新導向回來的操作。此時,我們可以執行付款,將資金轉入我們的商家帳戶。
  • PaymentCancelled:如果使用者取消審核流程,則將使用者從 PayPal 重定向到此操作。此時,您可能希望讓客戶選擇重試或與您聯絡。

授權付款以便稍後取得

#此場景與前一個案例非常相似。如果您嘗試預訂尚未上市的產品,您可能需要使用此方法。獲得這筆款項的步驟是:

  1. 授權付款:此呼叫的「意圖」參數應為「授權」。
  2. 取得付款:請記住,授權最多可保證 3 天,但您可以嘗試取得最長 29 天的付款。

為了實現這種類型的付款,我只在 PayPalPaymentService 類別中新增了一個新方法來捕獲付款:

public static Capture CapturePayment(string paymentId)
{
    var apiContext = PayPalConfiguration.GetAPIContext();

    var payment = Payment.Get(apiContext, paymentId);
    var auth = payment.transactions[0].related_resources[0].authorization;

    // Specify an amount to capture.  By setting 'is_final_capture' to true, all remaining funds held by the authorization will be released from the funding instrument.
    var capture = new Capture()
    {
        amount = new Amount()
        {
            currency = "USD",
            total = "4.54"
        },
        is_final_capture = true
    };

    // Capture an authorized payment by POSTing to
    // URI v1/payments/authorization/{authorization_id}/capture
    var responseCapture = auth.Capture(apiContext, capture);

    return responseCapture;
}

然後,我在 HomeController 中新增了兩個新操作來顯示此類付款:

public IActionResult AuthorizePayment()
{
    var payment = PayPalPaymentService.CreatePayment(GetBaseUrl(), "authorize");
    
    return Redirect(payment.GetApprovalUrl());
}

public IActionResult AuthorizeSuccessful(string paymentId, string token, string PayerID)
{
    // Capture Payment
    var capture = PayPalPaymentService.CapturePayment(paymentId);

    return View();
}
  • AuthorizePayment 是觸發付款的動作。它與先前的“CreatePayment”函數非常相似,但在本例中我們將“authorize”作為意圖參數傳遞。
  • AuthorizeSuccessful 是在成功批准 PayPal 付款後將重新導向您的客戶的操作。此時,我正在捕獲付款,但您可以將 paymentId 保存在資料庫中,並在需要時捕獲付款。

在這些程式碼範例中,為了簡單起見,我對付款變數值進行了硬編碼。在您的實際應用程式中,您可能會將它們包裝在將所有這些值作為變數的方法中,以便您可以動態設定和重複使用所有內容。

訂閱

這在 PayPal 中稱為「結算計劃」 - 您可以建立定期付款計劃,並透過建立結算協議為您的客戶訂閱結算計劃。使用 PayPal REST API,您可以建立、更新或刪除結算計畫;如果您想建立一個管理面板來管理您的企業的這些事情,您可能會使用這個東西。

向客戶創建經常性費用的步驟如下:

  1. 建立結算計畫啟動它。建立結算計劃後,它會處於「已建立」狀態。它需要透過發出 PATCH 請求來啟動。
  2. 建立結算協定執行:對「建立結算協定」呼叫的回應包括指向approval_url和execute_url的連結。我們需要獲得計費協議的批准,然後執行計費協議。

計費計畫

建立結算計畫

建立定義計費週期的計費計畫。這是我們在建立計劃時需要傳遞的參數的摘要。

  • 名称:计费计划的名称。
  • 说明:计费计划的说明。
  • 类型:对于固定次数的定期付款,允许的值为“FIXED”;对于手动取消之前重复的计划,允许的值为“INFINITE”。
  • 商户首选项:这是一个指定首选项的对象,例如设置费用、付款的最大失败尝试次数、返回 URL、取消 URL、通知 URL,PayPal 在付款后将在其中重定向用户。李>
  • 付款定义:此计划的付款定义数组。通常,该数组将具有一两个付款定义。如果我们想提供免费试用或折扣价格试用,那么我们会设置两种付款定义。第一个定义是试用期,第二个定义是定期付款。付款定义的属性包括名称类型(试用或常规)、频率(日、周、月、年)、 >频率间隔(如果我们将频率设置为“周”并将频率间隔设置为“1”,则我们定义每周付款)、向客户收费的金额,以及cycles 是总付款次数。 收费模式用于指定计划金额之外的运费和税费。

这是一个代码片段,展示了如何创建计费计划:

// Define the plan and attach the payment definitions and merchant preferences.
// More Information: https://developer.paypal.com/webapps/developer/docs/api/#create-a-plan
var billingPlan = new Plan
{
    name = "Tuts+ Plus",
    description = "Monthly plan for courses.",
    type = "fixed",
    // Define the merchant preferences.
    // More Information: https://developer.paypal.com/webapps/developer/docs/api/#merchantpreferences-object
    merchant_preferences = new MerchantPreferences()
    {
        setup_fee = GetCurrency("0"), // $0
        return_url = "returnURL", // Retrieve from config
        cancel_url = "cancelURL", // Retrieve from config
        auto_bill_amount = "YES",
        initial_fail_amount_action = "CONTINUE",
        max_fail_attempts = "0"
    },
    payment_definitions = new List<PaymentDefinition>
    {
        // Define a trial plan that will only charge $9.99 for the first
        // month. After that, the standard plan will take over for the
        // remaining 11 months of the year.
        new PaymentDefinition()
        {
            name = "Trial Plan",
            type = "TRIAL",
            frequency = "MONTH",
            frequency_interval = "1",
            amount = GetCurrency("0"), // Free for the 1st month
            cycles = "1",
            charge_models = new List<ChargeModel>
            {
                new ChargeModel()
                {
                    type = "TAX",
                    amount = GetCurrency("1.65") // If we need to charge Tax
                },
                new ChargeModel()
                {
                    type = "SHIPPING",
                    amount = GetCurrency("9.99") // If we need to charge for Shipping
                }
            }
        },
        // Define the standard payment plan. It will represent a monthly
        // plan for $19.99 USD that charges once month for 11 months.
        new PaymentDefinition
        {
            name = "Standard Plan",
            type = "REGULAR",
            frequency = "MONTH",
            frequency_interval = "1",
            amount = GetCurrency("15.00"),
            // > NOTE: For `IFNINITE` type plans, `cycles` should be 0 for a `REGULAR` `PaymentDefinition` object.
            cycles = "11",
            charge_models = new List<ChargeModel>
            {
                new ChargeModel
                {
                    type = "TAX",
                    amount = GetCurrency("2.47")
                },
                new ChargeModel()
                {
                    type = "SHIPPING",
                    amount = GetCurrency("9.99")
                }
            }
        }
    }
};

// Get PayPal Config
var apiContext = PayPalConfiguration.GetAPIContext();

// Create Plan
plan.Create(apiContext);

新创建的结算计划处于 CREATED 状态。将其激活为“活动”状态,以便您的客户可以订阅该计划。要激活该计划,我们需要发出 PATCH 请求:

// Activate the plan
var patchRequest = new PatchRequest()
{
    new Patch()
    {
        op = "replace",
        path = "/",
        value = new Plan() { state = "ACTIVE" }
    }
};
plan.Update(apiContext, patchRequest);

如您所见,PayPal 库是其 REST API 的直接包装器,这很好,但与 Stripe 等其他 API 相比,该 API 也非常复杂。因此,将所有 PayPal 通信包装在对象中,为我们的应用程序提供更清晰、更简单的 API,这确实是一个不错的选择。在这里您可以看到封装在多个带有参数的函数中的代码的样子:

public static Plan CreatePlanObject(string planName, string planDescription, string returnUrl, string cancelUrl,
    string frequency, int frequencyInterval, decimal planPrice,
    decimal shippingAmount = 0, decimal taxPercentage = 0, bool trial = false, int trialLength = 0, decimal trialPrice = 0)
{
    // Define the plan and attach the payment definitions and merchant preferences.
    // More Information: https://developer.paypal.com/docs/rest/api/payments.billing-plans/
    return new Plan
    {
        name = planName,
        description = planDescription,
        type = PlanType.Fixed,

        // Define the merchant preferences.
        // More Information: https://developer.paypal.com/webapps/developer/docs/api/#merchantpreferences-object
        merchant_preferences = new MerchantPreferences()
        {
            setup_fee = GetCurrency("1"),
            return_url = returnUrl,
            cancel_url = cancelUrl,
            auto_bill_amount = "YES",
            initial_fail_amount_action = "CONTINUE",
            max_fail_attempts = "0"
        },
        payment_definitions = GetPaymentDefinitions(trial, trialLength, trialPrice, frequency, frequencyInterval, planPrice, shippingAmount, taxPercentage)
    };
}

private static List<PaymentDefinition> GetPaymentDefinitions(bool trial, int trialLength, decimal trialPrice,
    string frequency, int frequencyInterval, decimal planPrice, decimal shippingAmount, decimal taxPercentage)
{
    var paymentDefinitions = new List<PaymentDefinition>();

    if (trial)
    {
        // Define a trial plan that will charge 'trialPrice' for 'trialLength'
        // After that, the standard plan will take over.
        paymentDefinitions.Add(
            new PaymentDefinition()
            {
                name = "Trial",
                type = "TRIAL",
                frequency = frequency,
                frequency_interval = frequencyInterval.ToString(),
                amount = GetCurrency(trialPrice.ToString()),
                cycles = trialLength.ToString(),
                charge_models = GetChargeModels(trialPrice, shippingAmount, taxPercentage)
            });
    }

    // Define the standard payment plan. It will represent a 'frequency' (monthly, etc)
    // plan for 'planPrice' that charges 'planPrice' (once a month) for #cycles.
    var regularPayment = new PaymentDefinition
    {
        name = "Standard Plan",
        type = "REGULAR",
        frequency = frequency,
        frequency_interval = frequencyInterval.ToString(),
        amount = GetCurrency(planPrice.ToString()),
        // > NOTE: For `IFNINITE` type plans, `cycles` should be 0 for a `REGULAR` `PaymentDefinition` object.
        cycles = "11",
        charge_models = GetChargeModels(trialPrice, shippingAmount, taxPercentage)
    };
    paymentDefinitions.Add(regularPayment);

    return paymentDefinitions;
}

private static List<ChargeModel> GetChargeModels(decimal planPrice, decimal shippingAmount, decimal taxPercentage)
{
    // Create the Billing Plan
    var chargeModels = new List<ChargeModel>();
    if (shippingAmount > 0)
    {
        chargeModels.Add(new ChargeModel()
        {
            type = "SHIPPING",
            amount = GetCurrency(shippingAmount.ToString())
        });
    }
    if (taxPercentage > 0)
    {
        chargeModels.Add(new ChargeModel()
        {
            type = "TAX",
            amount = GetCurrency(String.Format("{0:f2}", planPrice * taxPercentage / 100))
        });
    }

    return chargeModels;
}

更新结算计划

您可以通过提出“PATCH”请求来更新现有结算方案的信息。这是一个包装该调用的函数:

public static void UpdateBillingPlan(string planId, string path, object value)
{
    // PayPal Authentication tokens
    var apiContext = PayPalConfiguration.GetAPIContext();

    // Retrieve Plan
    var plan = Plan.Get(apiContext, planId);

    // Activate the plan
    var patchRequest = new PatchRequest()
    {
        new Patch()
        {
            op = "replace",
            path = path,
            value = value
        }
    };
    plan.Update(apiContext, patchRequest);
}

要更新计费计划描述,我们可以调用此函数并传递正确的参数:

UpdateBillingPlan(
    planId: "P-5FY40070P6526045UHFWUVEI", 
    path: "/", 
    value: new Plan { description = "new description" });

删除结算计划

理想情况下,当您不想接受新客户加入结算计划时,您需要将其更新为“非活动”状态。这不会影响该计划的现有计费协议。只需调用 UpdateBillingPlan 函数即可完成此操作:

UpdateBillingPlan(
    planId: "P-5FY40070P6526045UHFWUVEI",
    path: "/",
    value: new Plan { state = "INACTIVE" });

计费协议

创建计费协议

创建一个或多个结算计划后,您希望开始让客户注册您的订阅计划。为此,您需要收集客户详细信息并向 PayPal 提出请求。为了能够测试此功能,我向 HomeController 添加了几个操作:

public IActionResult Subscribe()
{
    var plan = PayPalSubscriptionsService.CreateBillingPlan("Tuts+ Plan", "Test plan for this article", GetBaseUrl());

    var subscription = PayPalSubscriptionsService.CreateBillingAgreement(plan.id, 
        new PayPal.Api.ShippingAddress
        {
            city = "London", 
            line1 = "line 1",
            postal_code = "SW1A 1AA",
            country_code = "GB"
        }, "Pedro Alonso", "Tuts+", DateTime.Now);
    
    return Redirect(subscription.GetApprovalUrl());
}

public IActionResult SubscribeSuccess(string token)
{
    // Execute approved agreement
    PayPalSubscriptionsService.ExecuteBillingAgreement(token);

    return View();
}

public IActionResult SubscribeCancel(string token)
{
    // TODO: Handle cancelled payment
    return RedirectToAction("Error");
}
  • 订阅:这是调用的第一个操作。它正在创建一个测试结算计划,然后创建该计划的结算协议(订阅),并将用户重定向到 PayPal 以确认付款。
  • 订阅成功:此操作是成功订阅后用作“返回 URL”的操作。协议令牌标识符在查询字符串中传递,我们使用此令牌来执行计费协议并使其处于活动状态。
  • SubscribeCancel: 此操作用作“取消 URL”。如果由于某种原因付款失败,或者您的客户取消了 PayPal 付款,用户将采取此操作,您需要处理此问题。也许可以提供重试的选项。

正如您在前面的代码片段中看到的,我已将大部分功能包装在几个方法中。第一个是上一节中解释的“CreateBillingPlan”。第二个是“CreateBillingAgreement”,用于为用户订阅计划:

public static Agreement CreateBillingAgreement(string planId, ShippingAddress shippingAddress, 
    string name, string description, DateTime startDate)
{
    // PayPal Authentication tokens
    var apiContext = PayPalConfiguration.GetAPIContext();

    var agreement = new Agreement()
    {
        name = name,
        description = description,
        start_date = startDate.ToString("yyyy-MM-ddTHH:mm:ss") + "Z",
        payer = new Payer() { payment_method = "paypal" },
        plan = new Plan() { id = planId },
        shipping_address = shippingAddress
    };
    
    var createdAgreement = agreement.Create(apiContext);
    return createdAgreement;
}

第三种方法是“ExecuteBillingAgreement”。成功订阅批准后,我们​​使用返回的令牌来激活订阅:

public static void ExecuteBillingAgreement(string token)
{
    // PayPal Authentication tokens
    var apiContext = PayPalConfiguration.GetAPIContext();

    var agreement = new Agreement() { token = token };
    var executedAgreement = agreement.Execute(apiContext);
}

暂停计费协议

使用此方法暂停协议:

public static void SuspendBillingAgreement(string agreementId)
{
    var apiContext = PayPalConfiguration.GetAPIContext();

    var agreement = new Agreement() { id = agreementId };
    agreement.Suspend(apiContext, new AgreementStateDescriptor()
        { note = "Suspending the agreement" });
}

重新激活计费协议

这个与上一个非常相似:

public static void ReactivateBillingAgreement(string agreementId)
{
    var apiContext = PayPalConfiguration.GetAPIContext();

    var agreement = new Agreement() { id = agreementId };
    agreement.ReActivate(apiContext, new AgreementStateDescriptor()
        { note = "Reactivating the agreement" });
}

取消计费协议

使用此功能取消计划:

public static void CancelBillingAgreement(string agreementId)
{
    var apiContext = PayPalConfiguration.GetAPIContext();

    var agreement = new Agreement() { id = agreementId };
    agreement.Cancel(apiContext, new AgreementStateDescriptor()
        { note = "Cancelling the agreement" });
}

更新计费协议

这个选项非常有限,我希望从这次通话中可以更改订阅计划,以升级或降级客户。与 Stripe 不同,单次调用不支持此功能。您需要通过取消当前协议并创建新的升级或降级协议来处理这种情况。这并不理想,但将来可能会改变。

结论

这是人们用来与 PayPal 集成的最常用功能的概述。他们的 API 比本文中解释的集成方法要大得多 - 您还可以发放退款和部分退款,并且他们针对本文涵盖的示例中的边缘情况提供了许多不同的选项。如果您有兴趣获得有关任何特定集成的更多详细信息,请在评论中留下建议。

以上是深入解析:PayPal整合第二部分:PayPal REST API的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
使用Next.js(後端集成)構建多租戶SaaS應用程序使用Next.js(後端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

如何使用Next.js(前端集成)構建多租戶SaaS應用程序如何使用Next.js(前端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:22 AM

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript:探索網絡語言的多功能性JavaScript:探索網絡語言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

JavaScript的演變:當前的趨勢和未來前景JavaScript的演變:當前的趨勢和未來前景Apr 10, 2025 am 09:33 AM

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

神秘的JavaScript:它的作用以及為什麼重要神秘的JavaScript:它的作用以及為什麼重要Apr 09, 2025 am 12:07 AM

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

Python還是JavaScript更好?Python還是JavaScript更好?Apr 06, 2025 am 12:14 AM

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。1.Python以简洁语法和丰富库生态著称,适用于数据分析和Web开发。2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

如何安裝JavaScript?如何安裝JavaScript?Apr 05, 2025 am 12:16 AM

JavaScript不需要安裝,因為它已內置於現代瀏覽器中。你只需文本編輯器和瀏覽器即可開始使用。 1)在瀏覽器環境中,通過標籤嵌入HTML文件中運行。 2)在Node.js環境中,下載並安裝Node.js後,通過命令行運行JavaScript文件。

在Quartz中如何在任務開始前發送通知?在Quartz中如何在任務開始前發送通知?Apr 04, 2025 pm 09:24 PM

如何在Quartz中提前發送任務通知在使用Quartz定時器進行任務調度時,任務的執行時間是由cron表達式設定的。現�...

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),