You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure AD B2C与支付网关集成方案咨询及示例需求

把Azure AD B2C和Stripe/PayPal集成,实现订阅用户专属访问

你可以通过「用户订阅状态存储+支付事件同步+登录时校验」三步实现需求,具体细节如下:

1. 给Azure AD B2C用户添加订阅状态属性

在Azure AD B2C后台扩展用户属性,新增一个名为subscriptionStatus的字段,用Active/Inactive两个枚举值标记用户是否处于有效订阅期。后续用户完成支付、续订或取消订阅时,都会同步更新这个字段。

2. 对接Stripe/PayPal的订阅事件

不管用哪个支付服务商,核心都是通过webhook将订阅状态同步到Azure AD B2C:

对接Stripe

  • 在Stripe后台配置webhook,监听customer.subscription.created(订阅创建)、customer.subscription.updated(订阅更新)、customer.subscription.deleted(订阅取消)三类事件;
  • 编写webhook处理接口:
    • 先验证Stripe的请求签名(防止伪造请求);
    • 根据事件类型,调用Microsoft Graph API找到对应的Azure AD B2C用户,将subscriptionStatus设为Active或Inactive;
    • 注意:需要在Azure AD中注册一个服务主体,给它分配更新用户属性的权限,用于调用Graph API。

对接PayPal

  • 在PayPal后台配置webhook,监听BILLING.SUBSCRIPTION.CREATED、BILLING.SUBSCRIPTION.UPDATED、BILLING.SUBSCRIPTION.CANCELLED三类事件;
  • 处理逻辑和Stripe一致:先验证PayPal签名,再根据事件类型更新Azure AD B2C用户的subscriptionStatus属性。

3. 用自定义策略实现登录时的订阅校验

内置用户流无法实现这类自定义校验,必须使用自定义策略(Custom Policy):

  • 首先在自定义策略中定义subscriptionStatus声明,用于从Azure AD B2C获取用户的订阅状态;
  • 添加一个验证步骤,检查subscriptionStatus是否为Active:
    • 若状态有效,继续执行登录流程;
    • 若状态无效,直接跳转错误页面,提示用户需要订阅才能访问。

以下是自定义策略的核心代码片段:

<!-- 定义订阅状态声明 -->
<BuildingBlocks>
  <ClaimsSchema>
    <ClaimType Id="subscriptionStatus">
      <DisplayName>订阅状态</DisplayName>
      <DataType>string</DataType>
    </ClaimType>
  </ClaimsSchema>
</BuildingBlocks>

<!-- 在登录流程中加入校验步骤 -->
<UserJourneys>
  <UserJourney Id="SignInWithSubscriptionCheck">
    <OrchestrationSteps>
      <!-- 本地账号MFA登录步骤 -->
      <OrchestrationStep Order="1" Type="ClaimsExchange">
        <ClaimsExchanges>
          <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
        </ClaimsExchanges>
      </OrchestrationStep>
      <!-- 获取用户订阅状态 -->
      <OrchestrationStep Order="2" Type="ClaimsExchange">
        <ClaimsExchanges>
          <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
        </ClaimsExchanges>
      </OrchestrationStep>
      <!-- 校验订阅状态有效性 -->
      <OrchestrationStep Order="3" Type="ClaimsExchange">
        <ClaimsExchanges>
          <ClaimsExchange Id="ValidateSubscriptionStatus" TechnicalProfileReferenceId="Validation-SubscriptionStatus" />
        </ClaimsExchanges>
      </OrchestrationStep>
      <!-- 后续令牌发放等步骤 -->
    </OrchestrationSteps>
  </UserJourney>
</UserJourneys>

<!-- 订阅状态校验的技术配置文件 -->
<ClaimsProviders>
  <ClaimsProvider>
    <DisplayName>验证逻辑</DisplayName>
    <TechnicalProfiles>
      <TechnicalProfile Id="Validation-SubscriptionStatus">
        <DisplayName>校验订阅状态</DisplayName>
        <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="subscriptionStatus" />
        </OutputClaims>
        <OutputClaimsTransformations>
          <OutputClaimsTransformation ReferenceId="AssertSubscriptionIsActive" />
        </OutputClaimsTransformations>
        <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
      </TechnicalProfile>
    </TechnicalProfiles>
  </ClaimsProvider>
</ClaimsProviders>

<!-- 断言订阅状态为Active,否则返回错误信息 -->
<ClaimsTransformations>
  <ClaimsTransformation Id="AssertSubscriptionIsActive" TransformationMethod="AssertStringClaimsAreEqual">
    <InputClaims>
      <InputClaim ClaimTypeReferenceId="subscriptionStatus" TransformationClaimType="inputClaim1" />
    </InputClaims>
    <InputParameters>
      <InputParameter Id="inputClaim2" DataType="string" Value="Active" />
      <InputParameter Id="stringComparison" DataType="string" Value="ordinalIgnoreCase" />
    </InputParameters>
    <OutputClaims>
      <OutputClaim ClaimTypeReferenceId="subscriptionStatus" />
    </OutputClaims>
    <OutputClaimsTransformations>
      <OutputClaimsTransformation ReferenceId="CreateSubscriptionInvalidError" />
    </OutputClaimsTransformations>
  </ClaimsTransformation>

  <ClaimsTransformation Id="CreateSubscriptionInvalidError" TransformationMethod="CreateStringClaim">
    <InputParameters>
      <InputParameter Id="value" DataType="string" Value="你的订阅已失效,请订阅后再访问应用。" />
    </InputParameters>
    <OutputClaims>
      <OutputClaim ClaimTypeReferenceId="errorMessage" />
    </OutputClaims>
  </ClaimsTransformation>
</ClaimsTransformations>

4. 示例项目参考

官方没有现成的端到端示例,但可以拆分组合现有资源:

  • 自定义策略部分:基于官方的「本地账号MFA登录」自定义策略模板,添加上述订阅校验逻辑;
  • 支付集成部分:参考Stripe/PayPal官方的订阅webhook示例,结合Microsoft Graph API更新用户属性的代码(用服务主体身份调用PATCH /users/{user-id}接口更新扩展属性)。

5. 注意事项

  • 必须验证webhook签名:Stripe和PayPal都提供签名验证机制,切勿跳过,防止恶意请求篡改用户订阅状态;
  • 关注同步延迟:用户取消订阅后,要确保webhook能及时触发,避免用户仍能访问应用;
  • 错误提示要友好:校验不通过时,给用户清晰的引导,比如跳转至订阅页面。

内容的提问来源于stack exchange,提问作者Duck45

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 10:15:08