du59131 2018-07-05 18:49
浏览 40
已采纳

为连接到一个条带帐户的单独站点为客户收取单独的源/卡

I have a question about making sure a site always charges the correct card (or bank account) for a particular customer on a particular site, when connecting multiple websites to a single Stripe account.

  • Site A - example1.com is connected to Stripe Account 1 via the API
  • Site B - example2.com is connected to Stripe Account 1 via the API

Customer 1 buys something on Site A with Credit Card 1 (say their business card) using their personal email account. Their email is saved with their customer id and their source is set to the business card. Then Customer 1 goes to Site B and buys something on Site B with Credit Card 2 (their personal card), but uses the same email address.

How can I tell Site B to use a particular card each time without updating the default card used for Site A?


Basically before creating an account, I check to make sure that the customer does not already have an account with that particular email. So if the same email is used on Site B as Site A, the same customer account is found for both sites. (Code simplified for explanation purposes.)

<?php
// namespace statement
// use \Stripe statements    


function exists ($email) {

  $customers = Customer::all(['email' => $email]);
  $count = 0;
  if (isset ($customers['data'])) {
    $count = count($customers['data']);
  }
  if ($count == 1) {
    $c = current ($customers['data']);
    if ($c instanceof Customer) {
      return $c->id;
    }
  }
  return false;

}

function create_customer ($email) {

  // Try to get the customer id by email.
  $cid = exists ($email);

  // Customer not found create them.
  if (!$cid) {
    try {
      $c = Customer::create([
        'email' => $e->mail,
      ]);
      return $c->id;
    } catch(Exception $e) {
      return false;
    }
  }
  return $cid;
}

function set_source ($cid, $token) {
  try {
    // This updates the default card, if I am understanding the documentation correctly.
    Customer::update($customer_id, ['source' => $token]);
    return true;
  } catch(Exception $e) {
    _sec_set_error_messages ($e, $sandbox_message);
  }
  return false;
}

function charge ($cid, $amount) {

  try {

    // This charges the default card, if I am understanding the documentation correctly.
    $charge = Charge::create([
      'amount' => $amount, 
      'currency' => 'usd',
      'customer' => $cid
    ]);

    return $charge;

  } catch (Exception $e) {
    return false;
  }


}

// check_my_db_for_customer_id();

// Create customer if not found.
$email = 'personal@example.com';
$cid = create_customer ($email);
if ($cid) {
  // save_to_my_db($email, $cid);
  set_source ($cid, $token);
  charge ($cid, $amount);
}

?>

The problem is, when charging the customer, how do tell each site to use a particular card? Can I save a source during my set_source function and then use that same source for a particular site when charging the card?

<?php

function set_source ($cid, $token) {
  try {
    // Need to add a source if one is found, not update the default.
    $get_source_id_somehow = Customer::update($customer_id, ['source' => $token]);
    return $get_source_id_somehow;
  } catch(Exception $e) {
    _sec_set_error_messages ($e, $sandbox_message);
  }
  return false;
}


function charge ($cid, $amount, $src) {

  try {

    $charge = Charge::create([
      'amount' => $amount, 
      'currency' => 'usd',
      'customer' => $cid,
      'source' => $src
    ]);

    return $charge;

  } catch (Exception $e) {
    return false;
  }

}

// check_my_db_for_customer_id_and_source_id();

// Create customer if not found.
$email = 'personal@example.com';
$cid = create_customer ($email);
if ($cid) {
  // save_to_my_db($email, $cid);
  $src = set_source ($cid, $token);
  // save_source_id_to_my_db ($src); ????
  charge ($cid, $amount, $src);
}

?>

Or is the only way to accomplish this to connect each site to its own separate Stripe account? Thanks.

EDIT - Additional Question

Would this be a security risk as well? If User 1 signs up on Site A, and then User 2 signs up on Site B using User 1's email, they definitely need to enter new payment details, so that User 1's card is not charged, when User 2 signs up.

EDIT 2 - Additional Thoughts

It seems that customer accounts need to be tied to a single site or application in some way. I don't know if it would validate, but maybe tagging the email or customer with that domain (and their user id) on that site, that way when you search for a matching customer you only find the customer with a matching email for that domain (and making sure it is not in use already by looking for the user id). Otherwise, User 2 could sign-up with User 1's email, and depending on the site may be allowed to change their email without validating the other one first, and in which case you could not update the Stripe customer account for User 2 on Site B without messing it up for User 1 on Site A.

This might lead to the same customer email in your Stripe account multiple times, but you could sort by the tag to find the individual domains at least and see which ones were in use by user id.

Now if User 1 signs up with personal@email.com on Site A it creates a Stripe account, tagged with Site A's domain and their user id. If we don't associate it with an account id, then User 1 might be able to switch their site's email to somethingnew@email.com (if Stripe isn't updated), then if User 2 signs up with personal@email.com on Site A and the account would now find the Stripe account tied to personal@email.com and both accounts would be running from the same Stripe account.

It almost seems like trying to match a customer before creating a new one is a bad security flaw. Or the Stripe account's email needs to stay updated with the site, but additional tags still need to be added to prevent the hijacking of User 1's Stripe account.

Possible Solution - Can anyone confirm?

Create a new Stripe account every time someone registers and tie it to the site's domain user id for future searches is the only secure way I can think to do it.

<?php

$customer = Customer::create([
    'email' => 'paying.user.3@example.com',
    'metadata' => [
      'site' => 'test/',
      'uid' => '6'
    ]
]);

Then you can search like this... Not the most elegant way as you lose the native way to paginate the search results in exchange for a finer result as metadata is not available via Customer::all() [that I know of].

<?php

$customers = Customer::all(['email' => $email]);
$matches = [];
foreach ($customers['data'] as $c) {
  if (
    $c->metadata && is_object ($c->metadata) && 
    $c->metadata->site && $c->metadata->site == 'test/' &&
    $c->metadata->uid && $c->metadata->uid == $uid
  ) {
    $matches[] = $c;
  }
}
  • 写回答

1条回答 默认 最新

  • douguangxiang0363 2018-07-06 18:46
    关注

    Received an answer from Stripe:

    You must use separate Stripe accounts for projects, websites, or businesses that operate independently from one another. When you activate a new account, it is subject to Stripe’s standard policies and pricing—it does not inherit any special status or other similar considerations that may apply to your existing account.

    With that said; you can create additional Stripe accounts at any time, each of which operates independently from one another. In doing this, instead of creating multiple user accounts with different email addresses, you can add new or existing accounts to one profile and quickly switch between them in the Dashboard (and forget having to remember any additional email and password combos).

    Here is the supporting documentation on managing multiple accounts: https://stripe.com/docs/multiple-accounts

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 模型在y分布之外的数据上预测能力不好如何解决
  • ¥15 processing提取音乐节奏
  • ¥15 gg加速器加速游戏时,提示不是x86架构
  • ¥15 python按要求编写程序
  • ¥15 Python输入字符串转化为列表排序具体见图,严格按照输入
  • ¥20 XP系统在重新启动后进不去桌面,一直黑屏。
  • ¥15 opencv图像处理,需要四个处理结果图
  • ¥15 无线移动边缘计算系统中的系统模型
  • ¥15 深度学习中的画图问题
  • ¥15 java报错:使用mybatis plus查询一个只返回一条数据的sql,却报错返回了1000多条