Merge pull request #609 from wrongecho/stripe

Add Stripe Payment integration for invoices
This commit is contained in:
Johnny 2023-02-07 17:19:26 -05:00 committed by GitHub
commit 01d786e0be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
320 changed files with 8047 additions and 4562 deletions

View File

@ -0,0 +1,142 @@
/* Variables */
* {
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
font-size: 16px;
-webkit-font-smoothing: antialiased;
display: flex;
justify-content: center;
align-content: center;
height: 100vh;
width: 100vw;
}
form {
width: 30vw;
min-width: 500px;
align-self: center;
box-shadow: 0px 0px 0px 0.5px rgba(50, 50, 93, 0.1),
0px 2px 5px 0px rgba(50, 50, 93, 0.1), 0px 1px 1.5px 0px rgba(0, 0, 0, 0.07);
border-radius: 7px;
padding: 40px;
}
.hidden {
display: none;
}
#payment-message {
color: rgb(105, 115, 134);
font-size: 16px;
line-height: 20px;
padding-top: 12px;
text-align: center;
}
#payment-element {
margin-bottom: 24px;
}
/* Buttons and links */
button {
background: #5469d4;
font-family: Arial, sans-serif;
color: #ffffff;
border-radius: 4px;
border: 0;
padding: 12px 16px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
display: block;
transition: all 0.2s ease;
box-shadow: 0px 4px 5.5px 0px rgba(0, 0, 0, 0.07);
width: 100%;
}
button:hover {
filter: contrast(115%);
}
button:disabled {
opacity: 0.5;
cursor: default;
}
/* spinner/processing state, errors */
.spinner,
.spinner:before,
.spinner:after {
border-radius: 50%;
}
.spinner {
color: #ffffff;
font-size: 22px;
text-indent: -99999px;
margin: 0px auto;
position: relative;
width: 20px;
height: 20px;
box-shadow: inset 0 0 0 2px;
-webkit-transform: translateZ(0);
-ms-transform: translateZ(0);
transform: translateZ(0);
}
.spinner:before,
.spinner:after {
position: absolute;
content: "";
}
.spinner:before {
width: 10.4px;
height: 20.4px;
background: #5469d4;
border-radius: 20.4px 0 0 20.4px;
top: -0.2px;
left: -0.2px;
-webkit-transform-origin: 10.4px 10.2px;
transform-origin: 10.4px 10.2px;
-webkit-animation: loading 2s infinite ease 1.5s;
animation: loading 2s infinite ease 1.5s;
}
.spinner:after {
width: 10.4px;
height: 10.2px;
background: #5469d4;
border-radius: 0 10.2px 10.2px 0;
top: -0.1px;
left: 10.2px;
-webkit-transform-origin: 0px 10.2px;
transform-origin: 0px 10.2px;
-webkit-animation: loading 2s infinite ease;
animation: loading 2s infinite ease;
}
@-webkit-keyframes loading {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes loading {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@media only screen and (max-width: 600px) {
form {
width: 80vw;
min-width: initial;
}
}

View File

@ -842,15 +842,23 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
if (CURRENT_DATABASE_VERSION == '0.4.0') {
mysqli_query($mysqli, "ALTER TABLE `logs` ADD `log_entity_id` INT NOT NULL DEFAULT '0' AFTER `log_user_id`");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.4.1'");
}
//if (CURRENT_DATABASE_VERSION == '0.4.1') {
// Insert queries here required to update to DB version 0.4.2
if (CURRENT_DATABASE_VERSION == '0.4.1') {
mysqli_query($mysqli, "ALTER TABLE settings ADD `config_stripe_account` TINYINT(1) NOT NULL DEFAULT '0' AFTER config_stripe_secret");
//Insert queries here required to update to DB version 0.4.2
//Then, update the database to the next sequential version
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.4.2'");
}
//if (CURRENT_DATABASE_VERSION == '0.4.2') {
// Insert queries here required to update to DB version 0.4.3
// Then, update the database to the next sequential version
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.4.2'");
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.4.3'");
//}
} else {

View File

@ -5,4 +5,4 @@
* It is used in conjunction with database_updates.php
*/
DEFINE("LATEST_DATABASE_VERSION", "0.4.1");
DEFINE("LATEST_DATABASE_VERSION", "0.4.2");

1
db.sql
View File

@ -1086,6 +1086,7 @@ CREATE TABLE `settings` (
`config_stripe_enable` tinyint(1) NOT NULL DEFAULT 0,
`config_stripe_publishable` varchar(255) DEFAULT NULL,
`config_stripe_secret` varchar(255) DEFAULT NULL,
`config_stripe_account` tinyint(1) NOT NULL DEFAULT 0,
`config_azure_client_id` varchar(200) DEFAULT NULL,
`config_azure_client_secret` varchar(200) DEFAULT NULL,
`config_module_enable_itdoc` tinyint(1) NOT NULL DEFAULT 1,

View File

@ -501,6 +501,7 @@ function sendSingleEmail($config_smtp_host, $config_smtp_username, $config_smtp_
try{
// Mail Server Settings
$mail->CharSet = "UTF-8"; // Specify UTF-8 charset to ensure symbols ($/£) load correctly
$mail->SMTPDebug = 0; // No Debugging
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = $config_smtp_host; // Specify SMTP server
@ -531,8 +532,9 @@ function sendSingleEmail($config_smtp_host, $config_smtp_username, $config_smtp_
}
catch(Exception $e) {
// If we couldn't send the message return the error, so we can log it
return "Message not sent. Mailer Error: {$mail->ErrorInfo}";
// If we couldn't send the message return the error, so we can log it in the database (truncated)
error_log("ITFlow - Failed to send email: " . $mail->ErrorInfo);
return substr("Mailer Error: $mail->ErrorInfo", 0, 150)."...";
}
}

View File

@ -72,6 +72,7 @@ $config_invoice_overdue_reminders = $row['config_invoice_overdue_reminders'];
$config_stripe_enable = $row['config_stripe_enable'];
$config_stripe_publishable = $row['config_stripe_publishable'];
$config_stripe_secret = $row['config_stripe_secret'];
$config_stripe_account = $row['config_stripe_account'];
// Modules
$config_module_enable_itdoc = $row['config_module_enable_itdoc'];

103
guest_ajax.php Normal file
View File

@ -0,0 +1,103 @@
<?php
/*
* guest_ajax.php
* Similar to post.php/ajax.php, but for unauthenticated requests using Asynchronous JavaScript
* Always returns data in JSON format, unless otherwise specified
*/
require_once("config.php");
require_once("functions.php");
/*
* Creates & Returns a Stripe Payment Intent for a particular invoice ID
*/
if (isset($_GET['stripe_create_pi'])) {
// Response header
header('Content-Type: application/json');
// Params from POST (guest_pay_invoice_stripe.js)
$jsonStr = file_get_contents('php://input');
$jsonObj = json_decode($jsonStr, true);
$invoice_id = intval($jsonObj['invoice_id']);
$url_key = mysqli_real_escape_string($mysqli, $jsonObj['url_key']);
// Query invoice details
$invoice_sql = mysqli_query(
$mysqli,
"SELECT * FROM invoices
LEFT JOIN clients ON invoice_client_id = client_id
WHERE invoice_id = $invoice_id
AND invoice_url_key = '$url_key'
AND invoice_status != 'Draft'
AND invoice_status != 'Paid'
AND invoice_status != 'Cancelled'
LIMIT 1"
);
if (!$invoice_sql || mysqli_num_rows($invoice_sql) !== 1) {
exit("Invalid Invoice ID/SQL query");
}
// Invoice exists - get details for payment
$row = mysqli_fetch_array($invoice_sql);
$invoice_prefix = htmlentities($row['invoice_prefix']);
$invoice_number = htmlentities($row['invoice_number']);
$invoice_amount = floatval($row['invoice_amount']);
$invoice_currency_code = htmlentities($row['invoice_currency_code']);
$client_id = $row['client_id'];
$client_name = htmlentities($row['client_name']);
// Add up all the payments for the invoice and get the total amount paid to the invoice
$sql_amount_paid = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS amount_paid FROM payments WHERE payment_invoice_id = $invoice_id");
$row = mysqli_fetch_array($sql_amount_paid);
$amount_paid = $row['amount_paid'];
$balance_to_pay = $invoice_amount - $amount_paid;
if (intval($balance_to_pay) == 0) {
exit("No balance outstanding");
}
// Setup Stripe
require_once('vendor/stripe-php-10.5.0/init.php');
$row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT config_stripe_enable, config_stripe_secret, config_stripe_account FROM settings WHERE company_id = 1"));
if ($row['config_stripe_enable'] == 0 || $row['config_stripe_account'] == 0) {
exit("Stripe not enabled / configured");
}
$config_stripe_secret = $row['config_stripe_secret'];
$pi_description = "ITFlow: $client_name payment of $invoice_currency_code $balance_to_pay for $client_name";
// Create a PaymentIntent with amount, currency and client details
try {
\Stripe\Stripe::setApiKey($config_stripe_secret);
$paymentIntent = \Stripe\PaymentIntent::create([
'amount' => intval($balance_to_pay * 100), // Times by 100 as Stripe expects values in cents
'currency' => $invoice_currency_code,
'description' => $pi_description,
'metadata' => [
'itflow_client_id' => $client_id,
'itflow_client_name' => $client_name,
'itflow_invoice_number' => $invoice_prefix . $invoice_number,
'itflow_invoice_id' => $invoice_id,
],
'automatic_payment_methods' => [
'enabled' => true,
],
]);
$output = [
'clientSecret' => $paymentIntent->client_secret,
];
echo json_encode($output);
} catch (Error $e) {
http_response_code(500);
echo json_encode(['error' => $e->getMessage()]);
}
}

View File

@ -1,120 +0,0 @@
<?php
// Still in development, for use with Stripe Pay - exit
exit();
include("config.php");
session_start();
if (isset($_POST['pay_invoice'])) {
$email = mysqli_real_escape_string($mysqli,$_POST['email']);
$password = md5(mysqli_real_escape_string($mysqli,$_POST['password']));
$sql = mysqli_query($mysqli,"SELECT * FROM users WHERE email = '$email' AND password = '$password'");
if (mysqli_num_rows($sql) == 1) {
$row = mysqli_fetch_array($sql);
$_SESSION['logged'] = TRUE;
$_SESSION['user_id'] = $row['user_id'];
$_SESSION['name'] = $row['name'];
header("Location: $config_start_page");
}else{
$response = "
<div class='alert alert-danger'>
Incorrect email or password.
<button class='close' data-dismiss='alert'>&times;</button>
</div>
";
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title><?php echo $config_company_name; ?> | Pay Invoice</title>
<!-- Custom fonts for this template-->
<link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
<!-- Custom styles for this template-->
<link href="css/sb-admin.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
</head>
<body class="bg-secondary">
<div class="container">
<div class="card card-login mx-auto mt-5 bg-dark">
<div class="card-header mt-2 text-white text-center"><h3>Invoice 103</h3></div>
<div class="card-body bg-white">
<center class="mb-3">
<i class="fab fa-fw fa-3x fa-cc-visa"></i>
<i class="fab fa-fw fa-3x fa-cc-mastercard"></i>
<i class="fab fa-fw fa-3x fa-cc-discover"></i>
<i class="fab fa-fw fa-3x fa-cc-amex"></i>
</center>
<?php if (isset($response)) { echo $response; } ?>
<form method="post">
<div class="form-group">
<label>Name on card</label>
<input type="text" name="name" class="form-control" placeholder="" required autofocus="autofocus">
</div>
<div class="form-group">
<label>Card number</label>
<input type="text" name="card_number" class="form-control" placeholder="" required>
</div>
<div class="form-row">
<div class="form-group col">
<label>Expiration</label>
<input type="text" name="expiration" class="form-control" placeholder="MM / YY" required>
</div>
<div class="form-group col">
<label>Security code</label>
<input type="text" name="security_code" class="form-control" placeholder="" required>
</div>
</div>
<div class="form-group">
<label>Postal code</label>
<input type="text" name="postal_code" class="form-control" placeholder="" required>
</div>
<button class="btn btn-success btn-block" type="submit" name="pay_invoice">Pay <strong>$100.00</strong></button>
</form>
</div>
</div>
</div>
<!-- Bootstrap core JavaScript-->
<script src="vendor/jquery/jquery.min.js"></script>
<script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- Core plugin JavaScript-->
<script src="vendor/jquery-easing/jquery.easing.min.js"></script>
<!-- Prevents resubmit on refresh or back -->
<script>
if ( window.history.replaceState ) {
window.history.replaceState( null, null, window.location.href );
}
</script>
</body>
</html>

View File

@ -0,0 +1,304 @@
<?php
require_once('guest_header.php');
// Define wording
DEFINE("WORDING_PAYMENT_FAILED", "<br><h2>There was an error verifying your payment. Please contact us for more information.</h2>");
// Setup Stripe
// Defaulting to company id of 1 (as multi-company is being removed)
$stripe_vars = mysqli_fetch_array(mysqli_query($mysqli, "SELECT config_stripe_enable, config_stripe_publishable, config_stripe_secret, config_stripe_account FROM settings WHERE company_id = 1"));
$config_stripe_enable = intval($stripe_vars['config_stripe_enable']);
$config_stripe_publishable = htmlentities($stripe_vars['config_stripe_publishable']);
$config_stripe_secret = htmlentities($stripe_vars['config_stripe_secret']);
$config_stripe_account = intval($stripe_vars['config_stripe_account']);
$os = trim(strip_tags(mysqli_real_escape_string($mysqli, getOS($user_agent))));
$browser = trim(strip_tags(mysqli_real_escape_string($mysqli, getWebBrowser($user_agent))));
// Check Stripe is configured
if ($config_stripe_enable == 0 || $config_stripe_account == 0 || empty($config_stripe_publishable) || empty($config_stripe_secret)) {
echo "<br><h2>Stripe payments not enabled/configured</h2>";
require_once('guest_footer.php');
exit();
}
// Show payment form
// Users are directed to this page with the invoice_id and url_key params to make a payment
if (isset($_GET['invoice_id'], $_GET['url_key']) && !isset($_GET['payment_intent'])) {
$invoice_url_key = mysqli_real_escape_string($mysqli, $_GET['url_key']);
$invoice_id = intval($_GET['invoice_id']);
// Query invoice details
$sql = mysqli_query(
$mysqli,
"SELECT * FROM invoices
LEFT JOIN clients ON invoice_client_id = client_id
LEFT JOIN companies ON invoices.company_id = companies.company_id
LEFT JOIN settings ON settings.company_id = companies.company_id
WHERE invoice_id = $invoice_id
AND invoice_url_key = '$invoice_url_key'
AND invoice_status != 'Draft'
AND invoice_status != 'Paid'
AND invoice_status != 'Cancelled'
LIMIT 1"
);
// Ensure we have a valid invoice
if (!$sql || mysqli_num_rows($sql) !== 1) {
echo "<br><h2>Oops, something went wrong! Please ensure you have the correct URL and have not already paid this invoice.</h2>";
require_once('guest_footer.php');
exit();
}
// Process invoice, client and company details/settings
$row = mysqli_fetch_array($sql);
$invoice_id = $row['invoice_id'];
$invoice_prefix = htmlentities($row['invoice_prefix']);
$invoice_number = htmlentities($row['invoice_number']);
$invoice_status = htmlentities($row['invoice_status']);
$invoice_date = $row['invoice_date'];
$invoice_due = $row['invoice_due'];
$invoice_amount = floatval($row['invoice_amount']);
$invoice_currency_code = htmlentities($row['invoice_currency_code']);
$client_id = $row['client_id'];
$client_name = htmlentities($row['client_name']);
$company_locale = htmlentities($row['company_locale']);
// Add up all the payments for the invoice and get the total amount paid to the invoice
$sql_amount_paid = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS amount_paid FROM payments WHERE payment_invoice_id = $invoice_id");
$row = mysqli_fetch_array($sql_amount_paid);
$amount_paid = $row['amount_paid'];
$balance_to_pay = $invoice_amount - $amount_paid;
// Get invoice items
$sql_invoice_items = mysqli_query($mysqli, "SELECT * FROM invoice_items WHERE item_invoice_id = $invoice_id ORDER BY item_id ASC");
// Set Currency Formatting
$currency_format = numfmt_create($company_locale, NumberFormatter::CURRENCY);
?>
<!-- Include Stripe JS (must be Stripe-hosted, not local) -->
<script src="https://js.stripe.com/v3/"></script>
<!-- jQuery -->
<script src="plugins/jquery/jquery.min.js"></script>
<br><br>
<div class="row">
<!-- Show invoice details -->
<div class="col-sm">
<h3>Payment for Invoice: <?php echo $invoice_prefix . $invoice_number ?></h3>
<br>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Product</th>
<th class="text-center">Qty</th>
<th class="text-right">Total</th>
</tr>
</thead>
<tbody>
<?php
$item_total = 0;
while ($row = mysqli_fetch_array($sql_invoice_items)) {
$item_name = htmlentities($row['item_name']);
$item_quantity = floatval($row['item_quantity']);
$item_total = floatval($row['item_total']);
?>
<tr>
<td><?php echo $item_name; ?></td>
<td><?php echo $item_quantity; ?></td>
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $item_total, $invoice_currency_code); ?></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
<i><?php if (intval($amount_paid) > 0) { ?> Already paid: <?php echo numfmt_format_currency($currency_format, $amount_paid, $invoice_currency_code); } ?></i>
</div>
<!-- End invoice details-->
<!-- Show Stripe payment form -->
<div class="col-sm offset-1">
<form id="payment-form">
<h1><?php echo numfmt_format_currency($currency_format, $balance_to_pay, $invoice_currency_code); ?></h1>
<input type="hidden" id="stripe_publishable_key" value="<?php echo $config_stripe_publishable ?>">
<input type="hidden" id="invoice_id" value="<?php echo $invoice_id ?>">
<input type="hidden" id="url_key" value="<?php echo $invoice_url_key ?>">
<br>
<div id="link-authentication-element">
<!--Stripe.js injects the Link Authentication Element-->
</div>
<div id="payment-element">
<!--Stripe.js injects the Payment Element-->
</div>
<br>
<button type="submit" id="submit" class="btn btn-primary text-bold" hidden="hidden">
<div class="spinner hidden" id="spinner"></div>
<span id="button-text">Pay Invoice</span>
</button>
<div id="payment-message" class="hidden"></div>
</form>
</div>
<!-- End Stripe payment form -->
</div>
<!-- Include local JS that powers stripe -->
<script src="js/guest_pay_invoice_stripe.js"></script>
<?php
// Process payment & redirect user back to invoice
// (Stripe will redirect back to this page upon payment success with the payment_intent and payment_intent_client_secret params set
} elseif (isset($_GET['payment_intent'], $_GET['payment_intent_client_secret'])) {
// Params from GET
$pi_id = mysqli_real_escape_string($mysqli, $_GET['payment_intent']);
$pi_cs = $_GET['payment_intent_client_secret'];
// Initialize stripe
require_once('vendor/stripe-php-10.5.0/init.php');
\Stripe\Stripe::setApiKey($config_stripe_secret);
// Check details of the PI
$pi_obj = \Stripe\PaymentIntent::retrieve($pi_id);
if ($pi_obj->client_secret !== $pi_cs) {
exit(WORDING_PAYMENT_FAILED);
} elseif ($pi_obj->status !== "succeeded") {
exit(WORDING_PAYMENT_FAILED);
} elseif ($pi_obj->amount !== $pi_obj->amount_received) {
// The invoice wasn't paid in full
// this should be flagged for manual review as would indicate something weird happening
exit(WORDING_PAYMENT_FAILED);
}
// Get details from PI
$pi_date = date('Y-m-d', $pi_obj->created);
$pi_invoice_id = intval($pi_obj->metadata->itflow_invoice_id);
$pi_client_id = intval($pi_obj->metadata->itflow_client_id);
$pi_amount_paid = floatval(($pi_obj->amount_received / 100));
$pi_currency = mysqli_real_escape_string($mysqli, $pi_obj->currency);
$pi_livemode = $pi_obj->livemode;
// Get/Check invoice (& client/primary contact)
$invoice_sql = mysqli_query(
$mysqli,
"SELECT * FROM invoices
LEFT JOIN clients ON invoice_client_id = client_id
LEFT JOIN contacts ON contact_id = primary_contact
LEFT JOIN companies ON invoices.company_id = companies.company_id
WHERE invoice_id = $pi_invoice_id
AND invoice_status != 'Draft'
AND invoice_status != 'Paid'
AND invoice_status != 'Cancelled'
LIMIT 1"
);
if (!$invoice_sql || mysqli_num_rows($invoice_sql) !== 1) {
exit(WORDING_PAYMENT_FAILED);
}
// Invoice exists - get details
$row = mysqli_fetch_array($invoice_sql);
$invoice_id = intval($row['invoice_id']);
$invoice_prefix = htmlentities($row['invoice_prefix']);
$invoice_number = htmlentities($row['invoice_number']);
$invoice_amount = floatval($row['invoice_amount']);
$invoice_currency_code = htmlentities($row['invoice_currency_code']);
$invoice_url_key = htmlentities($row['invoice_url_key']);
$invoice_company_id = intval($row['company_id']);
$client_id = $row['client_id'];
$client_name = htmlentities($row['client_name']);
$contact_name = $row['contact_name'];
$contact_email = $row['contact_email'];
$company_name = htmlentities($row['company_name']);
$company_phone = htmlentities($row['company_phone']);
$company_locale = htmlentities($row['company_locale']);
// Set Currency Formatting
$currency_format = numfmt_create($company_locale, NumberFormatter::CURRENCY);
// Add up all the payments for the invoice and get the total amount paid to the invoice already (if any)
$sql_amount_paid_previously = mysqli_query($mysqli, "SELECT SUM(payment_amount) AS amount_paid FROM payments WHERE payment_invoice_id = $invoice_id");
$row = mysqli_fetch_array($sql_amount_paid_previously);
$amount_paid_previously = $row['amount_paid'];
$balance_to_pay = $invoice_amount - $amount_paid_previously;
// Sanity check that the amount paid is exactly the invoice outstanding balance
if (intval($balance_to_pay) !== intval($pi_amount_paid)) {
exit("Something went wrong confirming this payment. Please get in touch.");
}
// Apply payment
// Update Invoice Status
mysqli_query($mysqli, "UPDATE invoices SET invoice_status = 'Paid' WHERE invoice_id = $invoice_id AND company_id = $invoice_company_id");
// Add Payment to History
mysqli_query($mysqli, "INSERT INTO payments SET payment_date = '$pi_date', payment_amount = '$pi_amount_paid', payment_currency_code = '$pi_currency', payment_account_id = $config_stripe_account, payment_method = 'Stripe', payment_reference = 'Stripe - $pi_id', payment_invoice_id = $invoice_id, company_id = $invoice_company_id");
mysqli_query($mysqli, "INSERT INTO history SET history_status = 'Paid', history_description = 'Payment added - $ip - $os - $browser', history_invoice_id = $invoice_id, company_id = $invoice_company_id");
// Logging
$extended_log_desc = '';
if (!$pi_livemode) {
$extended_log_desc = '(DEV MODE)';
}
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Payment', log_action = 'Create', log_description = 'Stripe payment of $pi_currency $pi_amount_paid against invoice $invoice_prefix$invoice_number - $pi_id $extended_log_desc', log_ip = '$ip', log_user_agent = '$user_agent', log_client_id = $pi_client_id, company_id = $invoice_company_id");
// Send email receipt
$sql_settings = mysqli_query($mysqli, "SELECT * FROM settings WHERE company_id = $invoice_company_id");
$row = mysqli_fetch_array($sql_settings);
$config_smtp_host = $row['config_smtp_host'];
$config_smtp_port = $row['config_smtp_port'];
$config_smtp_encryption = $row['config_smtp_encryption'];
$config_smtp_username = $row['config_smtp_username'];
$config_smtp_password = $row['config_smtp_password'];
$config_mail_from_email = $row['config_mail_from_email'];
$config_mail_from_name = $row['config_mail_from_name'];
$config_invoice_from_name = $row['config_invoice_from_name'];
$config_invoice_from_email = $row['config_invoice_from_email'];
if (!empty($config_smtp_host)) {
$subject = "Payment Received - Invoice $invoice_prefix$invoice_number";
$body = "Hello $contact_name,<br><br>We have received your payment in the amount of " . $pi_currency . $pi_amount_paid . " for invoice <a href='https://$config_base_url/guest_view_invoice.php?invoice_id=$invoice_id&url_key=$invoice_url_key'>$invoice_prefix$invoice_number</a>. Please keep this email as a receipt for your records.<br><br>Amount: " . numfmt_format_currency($currency_format, $pi_amount_paid, $invoice_currency_code) . "<br>Balance: " . numfmt_format_currency($currency_format, '0', $invoice_currency_code) . "<br><br>Thank you for your business!<br><br><br>~<br>$company_name<br>Billing Department<br>$config_invoice_from_email<br>$company_phone";
$mail = sendSingleEmail($config_smtp_host, $config_smtp_username, $config_smtp_password, $config_smtp_encryption, $config_smtp_port,
$config_invoice_from_email, $config_invoice_from_name,
$contact_email, $contact_name,
$subject, $body
);
// Email Logging
if ($mail === true) {
mysqli_query($mysqli, "INSERT INTO history SET history_status = 'Sent', history_description = 'Emailed Receipt!', history_invoice_id = $invoice_id, company_id = $invoice_company_id");
} else {
mysqli_query($mysqli, "INSERT INTO history SET history_status = 'Sent', history_description = 'Email Receipt Failed!', history_invoice_id = $invoice_id, company_id = $invoice_company_id");
mysqli_query($mysqli, "INSERT INTO notifications SET notification_type = 'Mail', notification = 'Failed to send email to $contact_email', notification_timestamp = NOW(), company_id = $invoice_company_id");
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Mail', log_action = 'Error', log_description = 'Failed to send email to $contact_email regarding $subject. $mail', log_ip = '$ip', log_user_agent = '$user_agent', company_id = $invoice_company_id");
}
}
// Redirect user to invoice
header('Location: //' . $config_base_url . '/guest_view_invoice.php?invoice_id=' . $pi_invoice_id . '&url_key=' . $invoice_url_key);
} else {
echo "<br><h2>Oops, something went wrong! Please raise a ticket if you believe this is an error.</h2>";
}
require_once('guest_footer.php');

View File

@ -122,7 +122,7 @@ if (isset($_GET['invoice_id'], $_GET['url_key'])) {
<?php
if ($config_stripe_enable == 1) {
?>
<a class="btn btn-success" href="guest_pay.php?invoice_id=<?php echo $invoice_id; ?>"><i class="fa fa-fw fa-credit-card"></i> Pay Online <small>(Coming Soon)</small></a>
<a class="btn btn-success" href="guest_pay_invoice_stripe.php?invoice_id=<?php echo $invoice_id; ?>&url_key=<?php echo $url_key; ?>"><i class="fa fa-fw fa-credit-card"></i> Pay Online <small>(Coming Soon)</small></a>
<?php } ?>
<?php } ?>
</div>

View File

@ -0,0 +1,120 @@
const stripe = Stripe(document.getElementById("stripe_publishable_key").value);
let elements;
initialize();
checkStatus();
document
.querySelector("#payment-form")
.addEventListener("submit", handleSubmit);
let emailAddress = '';
// Fetches a payment intent and captures the client secret
async function initialize() {
const { clientSecret } = await fetch("guest_ajax.php?stripe_create_pi=true", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
invoice_id: document.getElementById("invoice_id").value,
url_key: document.getElementById("url_key").value
}),
}).then((r) => r.json());
elements = stripe.elements({ clientSecret });
const linkAuthenticationElement = elements.create("linkAuthentication");
linkAuthenticationElement.mount("#link-authentication-element");
const paymentElementOptions = {
layout: "tabs",
};
const paymentElement = elements.create("payment", paymentElementOptions);
paymentElement.mount("#payment-element");
// Unhide the submit button once everything has loaded
document.getElementById("submit").hidden = false;
}
async function handleSubmit(e) {
e.preventDefault();
setLoading(true);
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: window.location.href,
receipt_email: emailAddress,
},
});
// This point will only be reached if there is an immediate error when
// confirming the payment. Otherwise, your customer will be redirected to
// your `return_url`. For some payment methods like iDEAL, your customer will
// be redirected to an intermediate site first to authorize the payment, then
// redirected to the `return_url`.
if (error.type === "card_error" || error.type === "validation_error") {
showMessage(error.message);
} else {
showMessage("An unexpected error occurred.");
}
setLoading(false);
}
// Fetches the payment intent status after payment submission
async function checkStatus() {
const clientSecret = new URLSearchParams(window.location.search).get(
"payment_intent_client_secret"
);
if (!clientSecret) {
return;
}
const { paymentIntent } = await stripe.retrievePaymentIntent(clientSecret);
switch (paymentIntent.status) {
case "succeeded":
showMessage("Payment succeeded!");
break;
case "processing":
showMessage("Your payment is processing.");
break;
case "requires_payment_method":
showMessage("Your payment was not successful, please try again.");
break;
default:
showMessage("Something went wrong.");
break;
}
}
// ------- UI helpers -------
function showMessage(messageText) {
const messageContainer = document.querySelector("#payment-message");
messageContainer.classList.remove("hidden");
messageContainer.textContent = messageText;
setTimeout(function () {
messageContainer.classList.add("hidden");
messageText.textContent = "";
}, 4000);
}
// Show a spinner on payment submission
function setLoading(isLoading) {
if (isLoading) {
// Disable the button and show a spinner
document.querySelector("#submit").disabled = true;
document.querySelector("#spinner").classList.remove("hidden");
document.querySelector("#button-text").classList.add("hidden");
} else {
document.querySelector("#submit").disabled = false;
document.querySelector("#spinner").classList.add("hidden");
document.querySelector("#button-text").classList.remove("hidden");
}
}

View File

@ -1060,8 +1060,9 @@ if(isset($_POST['edit_online_payment_settings'])){
$config_stripe_enable = intval($_POST['config_stripe_enable']);
$config_stripe_publishable = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['config_stripe_publishable'])));
$config_stripe_secret = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['config_stripe_secret'])));
$config_stripe_account = intval($_POST['config_stripe_account']);
mysqli_query($mysqli,"UPDATE settings SET config_stripe_enable = $config_stripe_enable, config_stripe_publishable = '$config_stripe_publishable', config_stripe_secret = '$config_stripe_secret' WHERE company_id = $session_company_id");
mysqli_query($mysqli,"UPDATE settings SET config_stripe_enable = $config_stripe_enable, config_stripe_publishable = '$config_stripe_publishable', config_stripe_secret = '$config_stripe_secret', config_stripe_account = $config_stripe_account WHERE company_id = $session_company_id");
//Logging
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Settings', log_action = 'Modify', log_description = '$session_name modified online payment settings', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_user_id = $session_user_id, company_id = $session_company_id");
@ -4218,8 +4219,8 @@ if(isset($_POST['add_payment'])){
if($email_receipt == 1){
$subject = "Payment Recieved - Invoice $invoice_prefix$invoice_number";
$body = "Hello $contact_name,<br><br>We have recieved your payment in the amount of " . numfmt_format_currency($currency_format, $amount, $invoice_currency_code) . " for invoice <a href='https://$config_base_url/guest_view_invoice.php?invoice_id=$invoice_id&url_key=$invoice_url_key'>$invoice_prefix$invoice_number</a>. Please keep this email as a receipt for your records.<br><br>Amount: " . numfmt_format_currency($currency_format, $amount, $invoice_currency_code) . "<br>Balance: " . numfmt_format_currency($currency_format, $invoice_balance, $invoice_currency_code) . "<br><br>Thank you for your business!<br><br><br>~<br>$company_name<br>Billing Department<br>$config_invoice_from_email<br>$company_phone";
$subject = "Payment Received - Invoice $invoice_prefix$invoice_number";
$body = "Hello $contact_name,<br><br>We have received your payment in the amount of " . numfmt_format_currency($currency_format, $amount, $invoice_currency_code) . " for invoice <a href='https://$config_base_url/guest_view_invoice.php?invoice_id=$invoice_id&url_key=$invoice_url_key'>$invoice_prefix$invoice_number</a>. Please keep this email as a receipt for your records.<br><br>Amount: " . numfmt_format_currency($currency_format, $amount, $invoice_currency_code) . "<br>Balance: " . numfmt_format_currency($currency_format, $invoice_balance, $invoice_currency_code) . "<br><br>Thank you for your business!<br><br><br>~<br>$company_name<br>Billing Department<br>$config_invoice_from_email<br>$company_phone";
$mail = sendSingleEmail($config_smtp_host, $config_smtp_username, $config_smtp_password, $config_smtp_encryption, $config_smtp_port,
$config_invoice_from_email, $config_invoice_from_name,
@ -4743,7 +4744,7 @@ if(isset($_GET['export_client_contacts_csv'])){
//Contacts
$sql = mysqli_query($mysqli,"SELECT * FROM contacts LEFT JOIN locations ON location_id = contact_location_id WHERE contact_client_id = $client_id AND contact_archived_at IS NULL ORDER BY contact_name ASC");
$num_rows = mysqli_num_rows($sql);
$num_rows = mysqli_num_rows($sql);
if($num_rows > 0){
$delimiter = ",";
@ -6015,7 +6016,7 @@ if(isset($_GET['export_client_software_csv'])){
//output all remaining data on a file pointer
fpassthru($f);
}
// Logging
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Software', log_action = 'Export', log_description = '$session_name exported $num_rows software license(s) to a CSV file', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_client_id = $client_id, log_user_id = $session_user_id, company_id = $session_company_id");

View File

@ -1,6 +1,10 @@
<?php
require_once("inc_all_settings.php"); ?>
require_once("inc_all_settings.php");
$sql_accounts = mysqli_query($mysqli, "SELECT * FROM accounts WHERE company_id = '$session_company_id'");
?>
<div class="alert alert-warning">
Work in Progress - Not yet functioning
@ -28,7 +32,7 @@ require_once("inc_all_settings.php"); ?>
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-eye"></i></span>
</div>
<input type="text" class="form-control" name="config_stripe_publishable" placeholder="Stripe Publishable API Key" value="<?php echo htmlentities($config_stripe_publishable); ?>">
<input type="text" class="form-control" name="config_stripe_publishable" placeholder="Stripe Publishable API Key (pk_...)" value="<?php echo htmlentities($config_stripe_publishable); ?>">
</div>
</div>
@ -38,7 +42,25 @@ require_once("inc_all_settings.php"); ?>
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
</div>
<input type="text" class="form-control" name="config_stripe_secret" placeholder="Stripe Secret API Key" value="<?php echo htmlentities($config_stripe_secret); ?>">
<input type="text" class="form-control" name="config_stripe_secret" placeholder="Stripe Secret API Key (sk_...)" value="<?php echo htmlentities($config_stripe_secret); ?>">
</div>
</div>
<div class="form-group">
<label>Account</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-piggy-bank"></i></span>
</div>
<select class="form-control" name="config_stripe_account">
<option value="">- Account -</option>
<?php
while ($row = mysqli_fetch_array($sql_accounts)) { ?>
<option value="<?php echo $row['account_id'] ?>" <?php if ($row['account_id'] == $config_stripe_account) { echo "selected"; } ?>><?php echo $row['account_name'] ?></option>
<?php }
?>
</select>
</div>
</div>

View File

@ -1,118 +0,0 @@
// A reference to Stripe.js initialized with your real test publishable API key.
var stripe = Stripe("<?php echo $stripe_publishable; ?>");
// The items the customer wants to buy
var purchase = {
items: [{ id: "xl-tshirt" }]
};
// Disable the button until we have Stripe set up on the page
document.querySelector("button").disabled = true;
fetch("/create.php", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(purchase)
})
.then(function(result) {
return result.json();
})
.then(function(data) {
var elements = stripe.elements();
var style = {
base: {
color: "#32325d",
fontFamily: 'Courier, monospace',
fontSmoothing: "antialiased",
fontSize: "16px",
"::placeholder": {
color: "#32325d"
}
},
invalid: {
fontFamily: 'Courier, monospace',
color: "#fa755a",
iconColor: "#fa755a"
}
};
var card = elements.create("card", { style: style });
// Stripe injects an iframe into the DOM
card.mount("#card-element");
card.on("change", function (event) {
// Disable the Pay button if there are no card details in the Element
document.querySelector("button").disabled = event.empty;
document.querySelector("#card-error").textContent = event.error ? event.error.message : "";
});
var form = document.getElementById("payment-form");
form.addEventListener("submit", function(event) {
event.preventDefault();
// Complete payment when the submit button is clicked
payWithCard(stripe, card, data.clientSecret);
});
});
// Calls stripe.confirmCardPayment
// If the card requires authentication Stripe shows a pop-up modal to
// prompt the user to enter authentication details without leaving your page.
var payWithCard = function(stripe, card, clientSecret) {
loading(true);
stripe
.confirmCardPayment(clientSecret, {
payment_method: {
card: card
}
})
.then(function(result) {
if (result.error) {
// Show error to your customer
showError(result.error.message);
} else {
// The payment succeeded!
orderComplete(result.paymentIntent.id);
}
});
};
/* ------- UI helpers ------- */
// Shows a success message when the payment is complete
var orderComplete = function(paymentIntentId) {
loading(false);
document
.querySelector(".result-message a")
.setAttribute(
"href",
"https://dashboard.stripe.com/test/payments/" + paymentIntentId
);
document.querySelector(".result-message").classList.remove("hidden");
document.querySelector("button").disabled = true;
};
// Show the customer the error from Stripe if their card fails to charge
var showError = function(errorMsgText) {
loading(false);
var errorMsg = document.querySelector("#card-error");
errorMsg.textContent = errorMsgText;
setTimeout(function() {
errorMsg.textContent = "";
}, 4000);
};
// Show a spinner on payment submission
var loading = function(isLoading) {
if (isLoading) {
// Disable the button and show a spinner
document.querySelector("button").disabled = true;
document.querySelector("#spinner").classList.remove("hidden");
document.querySelector("#button-text").classList.add("hidden");
} else {
document.querySelector("button").disabled = false;
document.querySelector("#spinner").classList.add("hidden");
document.querySelector("#button-text").classList.remove("hidden");
}
};

View File

@ -1,39 +0,0 @@
<?php
exit();
include("config.php");
include("check_login.php");
include("functions.php");
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Accept a card payment</title>
<meta name="description" content="A demo of a card payment on Stripe" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="global.css" />
<script src="https://js.stripe.com/v3/"></script>
<script src="https://polyfill.io/v3/polyfill.min.js?version=3.52.1&features=fetch"></script>
<script src="test_stripe_client.js" defer></script>
</head>
<body>
<!-- Display a payment form -->
<form id="payment-form">
<div id="card-element"><!--Stripe.js injects the Card Element--></div>
<button id="submit">
<div class="spinner hidden" id="spinner"></div>
<span id="button-text">Pay</span>
</button>
<p id="card-error" role="alert"></p>
<p class="result-message hidden">
Payment succeeded, see the result in your
<a href="" target="_blank">Stripe dashboard.</a> Refresh the page to pay again.
</p>
</form>
</body>
</html>

1
vendor/stripe-php-10.5.0/VERSION vendored Normal file
View File

@ -0,0 +1 @@
10.5.0

View File

@ -2,6 +2,8 @@
// File generated from our OpenAPI spec
require __DIR__ . '/lib/Util/ApiVersion.php';
// Stripe singleton
require __DIR__ . '/lib/Stripe.php';
@ -17,6 +19,7 @@ require __DIR__ . '/lib/Util/ObjectTypes.php';
// HttpClient
require __DIR__ . '/lib/HttpClient/ClientInterface.php';
require __DIR__ . '/lib/HttpClient/StreamingClientInterface.php';
require __DIR__ . '/lib/HttpClient/CurlClient.php';
// Exceptions
@ -53,6 +56,8 @@ require __DIR__ . '/lib/ApiOperations/Delete.php';
require __DIR__ . '/lib/ApiOperations/NestedResource.php';
require __DIR__ . '/lib/ApiOperations/Request.php';
require __DIR__ . '/lib/ApiOperations/Retrieve.php';
require __DIR__ . '/lib/ApiOperations/Search.php';
require __DIR__ . '/lib/ApiOperations/SingletonRetrieve.php';
require __DIR__ . '/lib/ApiOperations/Update.php';
// Plumbing
@ -66,25 +71,27 @@ require __DIR__ . '/lib/Service/AbstractService.php';
require __DIR__ . '/lib/Service/AbstractServiceFactory.php';
// StripeClient
require __DIR__ . '/lib/BaseStripeClientInterface.php';
require __DIR__ . '/lib/StripeClientInterface.php';
require __DIR__ . '/lib/StripeStreamingClientInterface.php';
require __DIR__ . '/lib/BaseStripeClient.php';
require __DIR__ . '/lib/StripeClient.php';
// Stripe API Resources
require __DIR__ . '/lib/Account.php';
require __DIR__ . '/lib/AccountLink.php';
require __DIR__ . '/lib/AlipayAccount.php';
require __DIR__ . '/lib/ApplePayDomain.php';
require __DIR__ . '/lib/ApplicationFee.php';
require __DIR__ . '/lib/ApplicationFeeRefund.php';
require __DIR__ . '/lib/Apps/Secret.php';
require __DIR__ . '/lib/Balance.php';
require __DIR__ . '/lib/BalanceTransaction.php';
require __DIR__ . '/lib/BankAccount.php';
require __DIR__ . '/lib/BillingPortal/Configuration.php';
require __DIR__ . '/lib/BillingPortal/Session.php';
require __DIR__ . '/lib/BitcoinReceiver.php';
require __DIR__ . '/lib/BitcoinTransaction.php';
require __DIR__ . '/lib/Capability.php';
require __DIR__ . '/lib/Card.php';
require __DIR__ . '/lib/CashBalance.php';
require __DIR__ . '/lib/Charge.php';
require __DIR__ . '/lib/Checkout/Session.php';
require __DIR__ . '/lib/Collection.php';
@ -94,6 +101,7 @@ require __DIR__ . '/lib/CreditNote.php';
require __DIR__ . '/lib/CreditNoteLineItem.php';
require __DIR__ . '/lib/Customer.php';
require __DIR__ . '/lib/CustomerBalanceTransaction.php';
require __DIR__ . '/lib/CustomerCashBalanceTransaction.php';
require __DIR__ . '/lib/Discount.php';
require __DIR__ . '/lib/Dispute.php';
require __DIR__ . '/lib/EphemeralKey.php';
@ -102,6 +110,13 @@ require __DIR__ . '/lib/Event.php';
require __DIR__ . '/lib/ExchangeRate.php';
require __DIR__ . '/lib/File.php';
require __DIR__ . '/lib/FileLink.php';
require __DIR__ . '/lib/FinancialConnections/Account.php';
require __DIR__ . '/lib/FinancialConnections/AccountOwner.php';
require __DIR__ . '/lib/FinancialConnections/AccountOwnership.php';
require __DIR__ . '/lib/FinancialConnections/Session.php';
require __DIR__ . '/lib/FundingInstructions.php';
require __DIR__ . '/lib/Identity/VerificationReport.php';
require __DIR__ . '/lib/Identity/VerificationSession.php';
require __DIR__ . '/lib/Invoice.php';
require __DIR__ . '/lib/InvoiceItem.php';
require __DIR__ . '/lib/InvoiceLineItem.php';
@ -114,10 +129,8 @@ require __DIR__ . '/lib/Issuing/Transaction.php';
require __DIR__ . '/lib/LineItem.php';
require __DIR__ . '/lib/LoginLink.php';
require __DIR__ . '/lib/Mandate.php';
require __DIR__ . '/lib/Order.php';
require __DIR__ . '/lib/OrderItem.php';
require __DIR__ . '/lib/OrderReturn.php';
require __DIR__ . '/lib/PaymentIntent.php';
require __DIR__ . '/lib/PaymentLink.php';
require __DIR__ . '/lib/PaymentMethod.php';
require __DIR__ . '/lib/Payout.php';
require __DIR__ . '/lib/Person.php';
@ -125,34 +138,47 @@ require __DIR__ . '/lib/Plan.php';
require __DIR__ . '/lib/Price.php';
require __DIR__ . '/lib/Product.php';
require __DIR__ . '/lib/PromotionCode.php';
require __DIR__ . '/lib/Quote.php';
require __DIR__ . '/lib/Radar/EarlyFraudWarning.php';
require __DIR__ . '/lib/Radar/ValueList.php';
require __DIR__ . '/lib/Radar/ValueListItem.php';
require __DIR__ . '/lib/Recipient.php';
require __DIR__ . '/lib/RecipientTransfer.php';
require __DIR__ . '/lib/Refund.php';
require __DIR__ . '/lib/Reporting/ReportRun.php';
require __DIR__ . '/lib/Reporting/ReportType.php';
require __DIR__ . '/lib/Review.php';
require __DIR__ . '/lib/SearchResult.php';
require __DIR__ . '/lib/SetupAttempt.php';
require __DIR__ . '/lib/SetupIntent.php';
require __DIR__ . '/lib/ShippingRate.php';
require __DIR__ . '/lib/Sigma/ScheduledQueryRun.php';
require __DIR__ . '/lib/SKU.php';
require __DIR__ . '/lib/Source.php';
require __DIR__ . '/lib/SourceTransaction.php';
require __DIR__ . '/lib/Subscription.php';
require __DIR__ . '/lib/SubscriptionItem.php';
require __DIR__ . '/lib/SubscriptionSchedule.php';
require __DIR__ . '/lib/TaxCode.php';
require __DIR__ . '/lib/TaxId.php';
require __DIR__ . '/lib/TaxRate.php';
require __DIR__ . '/lib/Terminal/Configuration.php';
require __DIR__ . '/lib/Terminal/ConnectionToken.php';
require __DIR__ . '/lib/Terminal/Location.php';
require __DIR__ . '/lib/Terminal/Reader.php';
require __DIR__ . '/lib/ThreeDSecure.php';
require __DIR__ . '/lib/TestHelpers/TestClock.php';
require __DIR__ . '/lib/Token.php';
require __DIR__ . '/lib/Topup.php';
require __DIR__ . '/lib/Transfer.php';
require __DIR__ . '/lib/TransferReversal.php';
require __DIR__ . '/lib/Treasury/CreditReversal.php';
require __DIR__ . '/lib/Treasury/DebitReversal.php';
require __DIR__ . '/lib/Treasury/FinancialAccount.php';
require __DIR__ . '/lib/Treasury/FinancialAccountFeatures.php';
require __DIR__ . '/lib/Treasury/InboundTransfer.php';
require __DIR__ . '/lib/Treasury/OutboundPayment.php';
require __DIR__ . '/lib/Treasury/OutboundTransfer.php';
require __DIR__ . '/lib/Treasury/ReceivedCredit.php';
require __DIR__ . '/lib/Treasury/ReceivedDebit.php';
require __DIR__ . '/lib/Treasury/Transaction.php';
require __DIR__ . '/lib/Treasury/TransactionEntry.php';
require __DIR__ . '/lib/UsageRecord.php';
require __DIR__ . '/lib/UsageRecordSummary.php';
require __DIR__ . '/lib/WebhookEndpoint.php';
@ -162,8 +188,10 @@ require __DIR__ . '/lib/Service/AccountService.php';
require __DIR__ . '/lib/Service/AccountLinkService.php';
require __DIR__ . '/lib/Service/ApplePayDomainService.php';
require __DIR__ . '/lib/Service/ApplicationFeeService.php';
require __DIR__ . '/lib/Service/Apps/SecretService.php';
require __DIR__ . '/lib/Service/BalanceService.php';
require __DIR__ . '/lib/Service/BalanceTransactionService.php';
require __DIR__ . '/lib/Service/BillingPortal/ConfigurationService.php';
require __DIR__ . '/lib/Service/BillingPortal/SessionService.php';
require __DIR__ . '/lib/Service/ChargeService.php';
require __DIR__ . '/lib/Service/Checkout/SessionService.php';
@ -177,6 +205,10 @@ require __DIR__ . '/lib/Service/EventService.php';
require __DIR__ . '/lib/Service/ExchangeRateService.php';
require __DIR__ . '/lib/Service/FileService.php';
require __DIR__ . '/lib/Service/FileLinkService.php';
require __DIR__ . '/lib/Service/FinancialConnections/AccountService.php';
require __DIR__ . '/lib/Service/FinancialConnections/SessionService.php';
require __DIR__ . '/lib/Service/Identity/VerificationReportService.php';
require __DIR__ . '/lib/Service/Identity/VerificationSessionService.php';
require __DIR__ . '/lib/Service/InvoiceService.php';
require __DIR__ . '/lib/Service/InvoiceItemService.php';
require __DIR__ . '/lib/Service/Issuing/AuthorizationService.php';
@ -185,15 +217,15 @@ require __DIR__ . '/lib/Service/Issuing/CardholderService.php';
require __DIR__ . '/lib/Service/Issuing/DisputeService.php';
require __DIR__ . '/lib/Service/Issuing/TransactionService.php';
require __DIR__ . '/lib/Service/MandateService.php';
require __DIR__ . '/lib/Service/OrderService.php';
require __DIR__ . '/lib/Service/OrderReturnService.php';
require __DIR__ . '/lib/Service/PaymentIntentService.php';
require __DIR__ . '/lib/Service/PaymentLinkService.php';
require __DIR__ . '/lib/Service/PaymentMethodService.php';
require __DIR__ . '/lib/Service/PayoutService.php';
require __DIR__ . '/lib/Service/PlanService.php';
require __DIR__ . '/lib/Service/PriceService.php';
require __DIR__ . '/lib/Service/ProductService.php';
require __DIR__ . '/lib/Service/PromotionCodeService.php';
require __DIR__ . '/lib/Service/QuoteService.php';
require __DIR__ . '/lib/Service/Radar/EarlyFraudWarningService.php';
require __DIR__ . '/lib/Service/Radar/ValueListService.php';
require __DIR__ . '/lib/Service/Radar/ValueListItemService.php';
@ -203,30 +235,60 @@ require __DIR__ . '/lib/Service/Reporting/ReportTypeService.php';
require __DIR__ . '/lib/Service/ReviewService.php';
require __DIR__ . '/lib/Service/SetupAttemptService.php';
require __DIR__ . '/lib/Service/SetupIntentService.php';
require __DIR__ . '/lib/Service/ShippingRateService.php';
require __DIR__ . '/lib/Service/Sigma/ScheduledQueryRunService.php';
require __DIR__ . '/lib/Service/SkuService.php';
require __DIR__ . '/lib/Service/SourceService.php';
require __DIR__ . '/lib/Service/SubscriptionService.php';
require __DIR__ . '/lib/Service/SubscriptionItemService.php';
require __DIR__ . '/lib/Service/SubscriptionScheduleService.php';
require __DIR__ . '/lib/Service/TaxCodeService.php';
require __DIR__ . '/lib/Service/TaxRateService.php';
require __DIR__ . '/lib/Service/Terminal/ConfigurationService.php';
require __DIR__ . '/lib/Service/Terminal/ConnectionTokenService.php';
require __DIR__ . '/lib/Service/Terminal/LocationService.php';
require __DIR__ . '/lib/Service/Terminal/ReaderService.php';
require __DIR__ . '/lib/Service/TestHelpers/CustomerService.php';
require __DIR__ . '/lib/Service/TestHelpers/Issuing/CardService.php';
require __DIR__ . '/lib/Service/TestHelpers/RefundService.php';
require __DIR__ . '/lib/Service/TestHelpers/Terminal/ReaderService.php';
require __DIR__ . '/lib/Service/TestHelpers/TestClockService.php';
require __DIR__ . '/lib/Service/TestHelpers/Treasury/InboundTransferService.php';
require __DIR__ . '/lib/Service/TestHelpers/Treasury/OutboundPaymentService.php';
require __DIR__ . '/lib/Service/TestHelpers/Treasury/OutboundTransferService.php';
require __DIR__ . '/lib/Service/TestHelpers/Treasury/ReceivedCreditService.php';
require __DIR__ . '/lib/Service/TestHelpers/Treasury/ReceivedDebitService.php';
require __DIR__ . '/lib/Service/TokenService.php';
require __DIR__ . '/lib/Service/TopupService.php';
require __DIR__ . '/lib/Service/TransferService.php';
require __DIR__ . '/lib/Service/Treasury/CreditReversalService.php';
require __DIR__ . '/lib/Service/Treasury/DebitReversalService.php';
require __DIR__ . '/lib/Service/Treasury/FinancialAccountService.php';
require __DIR__ . '/lib/Service/Treasury/InboundTransferService.php';
require __DIR__ . '/lib/Service/Treasury/OutboundPaymentService.php';
require __DIR__ . '/lib/Service/Treasury/OutboundTransferService.php';
require __DIR__ . '/lib/Service/Treasury/ReceivedCreditService.php';
require __DIR__ . '/lib/Service/Treasury/ReceivedDebitService.php';
require __DIR__ . '/lib/Service/Treasury/TransactionService.php';
require __DIR__ . '/lib/Service/Treasury/TransactionEntryService.php';
require __DIR__ . '/lib/Service/WebhookEndpointService.php';
// Service factories
require __DIR__ . '/lib/Service/CoreServiceFactory.php';
require __DIR__ . '/lib/Service/Apps/AppsServiceFactory.php';
require __DIR__ . '/lib/Service/BillingPortal/BillingPortalServiceFactory.php';
require __DIR__ . '/lib/Service/Checkout/CheckoutServiceFactory.php';
require __DIR__ . '/lib/Service/CoreServiceFactory.php';
require __DIR__ . '/lib/Service/FinancialConnections/FinancialConnectionsServiceFactory.php';
require __DIR__ . '/lib/Service/Identity/IdentityServiceFactory.php';
require __DIR__ . '/lib/Service/Issuing/IssuingServiceFactory.php';
require __DIR__ . '/lib/Service/Radar/RadarServiceFactory.php';
require __DIR__ . '/lib/Service/Reporting/ReportingServiceFactory.php';
require __DIR__ . '/lib/Service/Sigma/SigmaServiceFactory.php';
require __DIR__ . '/lib/Service/Terminal/TerminalServiceFactory.php';
require __DIR__ . '/lib/Service/TestHelpers/Issuing/IssuingServiceFactory.php';
require __DIR__ . '/lib/Service/TestHelpers/Terminal/TerminalServiceFactory.php';
require __DIR__ . '/lib/Service/TestHelpers/TestHelpersServiceFactory.php';
require __DIR__ . '/lib/Service/TestHelpers/Treasury/TreasuryServiceFactory.php';
require __DIR__ . '/lib/Service/Treasury/TreasuryServiceFactory.php';
// OAuth
require __DIR__ . '/lib/OAuth.php';

View File

@ -20,12 +20,14 @@ namespace Stripe;
* @property \Stripe\StripeObject $capabilities
* @property bool $charges_enabled Whether the account can create live charges.
* @property \Stripe\StripeObject $company
* @property \Stripe\StripeObject $controller
* @property string $country The account's country.
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property int $created Time at which the account was connected. Measured in seconds since the Unix epoch.
* @property string $default_currency Three-letter ISO currency code representing the default currency for the account. This must be a currency that <a href="https://stripe.com/docs/payouts">Stripe supports in the account's country</a>.
* @property bool $details_submitted Whether account details have been submitted. Standard accounts cannot receive payouts before this is true.
* @property null|string $email The primary user's email address.
* @property \Stripe\Collection $external_accounts External accounts (bank accounts and debit cards) currently attached to this account
* @property null|string $email An email address associated with the account. You can treat this as metadata: it is not used for authentication or messaging account holders.
* @property \Stripe\Collection<\Stripe\BankAccount|\Stripe\Card> $external_accounts External accounts (bank accounts and debit cards) currently attached to this account
* @property \Stripe\StripeObject $future_requirements
* @property \Stripe\Person $individual <p>This is an object representing a person associated with a Stripe account.</p><p>A platform cannot access a Standard or Express account's persons after the account starts onboarding, such as after generating an account link for the account. See the <a href="https://stripe.com/docs/connect/standard-accounts">Standard onboarding</a> or <a href="https://stripe.com/docs/connect/express-accounts">Express onboarding documentation</a> for information about platform pre-filling and account onboarding steps.</p><p>Related guide: <a href="https://stripe.com/docs/connect/identity-verification-api#person-information">Handling Identity Verification with the API</a>.</p>
* @property \Stripe\StripeObject $metadata Set of <a href="https://stripe.com/docs/api/metadata">key-value pairs</a> that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
* @property bool $payouts_enabled Whether Stripe can send payouts to this account.
@ -49,15 +51,6 @@ class Account extends ApiResource
const BUSINESS_TYPE_INDIVIDUAL = 'individual';
const BUSINESS_TYPE_NON_PROFIT = 'non_profit';
const CAPABILITY_CARD_PAYMENTS = 'card_payments';
const CAPABILITY_LEGACY_PAYMENTS = 'legacy_payments';
const CAPABILITY_PLATFORM_PAYMENTS = 'platform_payments';
const CAPABILITY_TRANSFERS = 'transfers';
const CAPABILITY_STATUS_ACTIVE = 'active';
const CAPABILITY_STATUS_INACTIVE = 'inactive';
const CAPABILITY_STATUS_PENDING = 'pending';
const TYPE_CUSTOM = 'custom';
const TYPE_EXPRESS = 'express';
const TYPE_STANDARD = 'standard';
@ -88,6 +81,25 @@ class Account extends ApiResource
return parent::instanceUrl();
}
/**
* @param null|array|string $id the ID of the account to retrieve, or an
* options array containing an `id` key
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Account
*/
public static function retrieve($id = null, $opts = null)
{
if (!$opts && \is_string($id) && 'sk_' === \substr($id, 0, 3)) {
$opts = $id;
$id = null;
}
return self::_retrieve($id, $opts);
}
public function serializeParameters($force = false)
{
$update = parent::serializeParameters($force);
@ -139,25 +151,6 @@ class Account extends ApiResource
return $updateArr;
}
/**
* @param null|array|string $id the ID of the account to retrieve, or an
* options array containing an `id` key
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Account
*/
public static function retrieve($id = null, $opts = null)
{
if (!$opts && \is_string($id) && 'sk_' === \substr($id, 0, 3)) {
$opts = $id;
$id = null;
}
return self::_retrieve($id, $opts);
}
/**
* @param null|array $clientId
* @param null|array|string $opts
@ -182,25 +175,7 @@ class Account extends ApiResource
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Collection the list of persons
*/
public function persons($params = null, $opts = null)
{
$url = $this->instanceUrl() . '/persons';
list($response, $opts) = $this->_request('get', $url, $params, $opts);
$obj = Util\Util::convertToStripeObject($response, $opts);
$obj->setLastResponse($response);
return $obj;
}
/**
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return Account the rejected account
* @return \Stripe\Account the rejected account
*/
public function reject($params = null, $opts = null)
{
@ -211,12 +186,6 @@ class Account extends ApiResource
return $this;
}
/*
* Capabilities methods
* We can not add the capabilities() method today as the Account object already has a
* capabilities property which is a hash and not the sub-list of capabilities.
*/
const PATH_CAPABILITIES = '/capabilities';
/**
@ -226,7 +195,7 @@ class Account extends ApiResource
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Collection the list of capabilities
* @return \Stripe\Collection<\Stripe\Capability> the list of capabilities
*/
public static function allCapabilities($id, $params = null, $opts = null)
{
@ -262,7 +231,6 @@ class Account extends ApiResource
{
return self::_updateNestedResource($id, static::PATH_CAPABILITIES, $capabilityId, $params, $opts);
}
const PATH_EXTERNAL_ACCOUNTS = '/external_accounts';
/**
@ -272,7 +240,7 @@ class Account extends ApiResource
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Collection the list of external accounts (BankAccount or Card)
* @return \Stripe\Collection<\Stripe\BankAccount|\Stripe\Card> the list of external accounts (BankAccount or Card)
*/
public static function allExternalAccounts($id, $params = null, $opts = null)
{
@ -337,7 +305,6 @@ class Account extends ApiResource
{
return self::_updateNestedResource($id, static::PATH_EXTERNAL_ACCOUNTS, $externalAccountId, $params, $opts);
}
const PATH_LOGIN_LINKS = '/login_links';
/**
@ -353,7 +320,6 @@ class Account extends ApiResource
{
return self::_createNestedResource($id, static::PATH_LOGIN_LINKS, $params, $opts);
}
const PATH_PERSONS = '/persons';
/**
@ -363,7 +329,7 @@ class Account extends ApiResource
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Collection the list of persons
* @return \Stripe\Collection<\Stripe\Person> the list of persons
*/
public static function allPersons($id, $params = null, $opts = null)
{

View File

@ -45,6 +45,21 @@ trait Request
return [$resp->json, $options];
}
/**
* @param string $method HTTP method ('get', 'post', etc.)
* @param string $url URL for the request
* @param callable $readBodyChunk function that will receive chunks of data from a successful request body
* @param array $params list of parameters for the request
* @param null|array|string $options
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*/
protected function _requestStream($method, $url, $readBodyChunk, $params = [], $options = null)
{
$opts = $this->_opts->merge($options);
static::_staticStreamingRequest($method, $url, $readBodyChunk, $params, $opts);
}
/**
* @param string $method HTTP method ('get', 'post', etc.)
* @param string $url URL for the request
@ -65,4 +80,21 @@ trait Request
return [$response, $opts];
}
/**
* @param string $method HTTP method ('get', 'post', etc.)
* @param string $url URL for the request
* @param callable $readBodyChunk function that will receive chunks of data from a successful request body
* @param array $params list of parameters for the request
* @param null|array|string $options
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*/
protected static function _staticStreamingRequest($method, $url, $readBodyChunk, $params, $options)
{
$opts = \Stripe\Util\RequestOptions::parse($options);
$baseUrl = isset($opts->apiBase) ? $opts->apiBase : static::baseUrl();
$requestor = new \Stripe\ApiRequestor($opts->apiKey, $baseUrl);
$requestor->requestStream($method, $url, $readBodyChunk, $params, $opts->headers);
}
}

View File

@ -0,0 +1,37 @@
<?php
namespace Stripe\ApiOperations;
/**
* Trait for searchable resources.
*
* This trait should only be applied to classes that derive from StripeObject.
*/
trait Search
{
/**
* @param string $searchUrl
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\SearchResult of ApiResources
*/
protected static function _searchResource($searchUrl, $params = null, $opts = null)
{
self::_validateParams($params);
list($response, $opts) = static::_staticRequest('get', $searchUrl, $params, $opts);
$obj = \Stripe\Util\Util::convertToStripeObject($response->json, $opts);
if (!($obj instanceof \Stripe\SearchResult)) {
throw new \Stripe\Exception\UnexpectedValueException(
'Expected type ' . \Stripe\SearchResult::class . ', got "' . \get_class($obj) . '" instead.'
);
}
$obj->setLastResponse($response);
$obj->setFilters($params);
return $obj;
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace Stripe\ApiOperations;
/**
* Trait for retrievable singleton resources. Adds a `retrieve()` static method to the
* class.
*
* This trait should only be applied to classes that derive from SingletonApiResource.
*/
trait SingletonRetrieve
{
/**
* @param array|string $id the ID of the API resource to retrieve,
* or an options array containing an `id` key
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return static
*/
public static function retrieve($opts = null)
{
$opts = \Stripe\Util\RequestOptions::parse($opts);
$instance = new static(null, $opts);
$instance->refresh();
return $instance;
}
}

View File

@ -37,6 +37,10 @@ trait Update
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return static the saved resource
*
* @deprecated The `save` method is deprecated and will be removed in a
* future major version of the library. Use the static method `update`
* on the resource instead.
*/
public function save($opts = null)
{

View File

@ -21,6 +21,10 @@ class ApiRequestor
* @var HttpClient\ClientInterface
*/
private static $_httpClient;
/**
* @var HttpClient\StreamingClientInterface
*/
private static $_streamingHttpClient;
/**
* @var RequestTelemetry
@ -123,6 +127,26 @@ class ApiRequestor
return [$resp, $myApiKey];
}
/**
* @param string $method
* @param string $url
* @param callable $readBodyChunkCallable
* @param null|array $params
* @param null|array $headers
*
* @throws Exception\ApiErrorException
*/
public function requestStream($method, $url, $readBodyChunkCallable, $params = null, $headers = null)
{
$params = $params ?: [];
$headers = $headers ?: [];
list($rbody, $rcode, $rheaders, $myApiKey) =
$this->_requestRawStreaming($method, $url, $params, $headers, $readBodyChunkCallable);
if ($rcode >= 300) {
$this->_interpretResponse($rbody, $rcode, $rheaders);
}
}
/**
* @param string $rbody a JSON string
* @param int $rcode
@ -271,9 +295,8 @@ class ApiRequestor
/**
* @static
*
* @param string $disabledFunctionsOutput - String value of the 'disable_function' setting, as output by \ini_get('disable_functions')
* @param string $disableFunctionsOutput - String value of the 'disable_function' setting, as output by \ini_get('disable_functions')
* @param string $functionName - Name of the function we are interesting in seeing whether or not it is disabled
* @param mixed $disableFunctionsOutput
*
* @return bool
*/
@ -328,18 +351,7 @@ class ApiRequestor
];
}
/**
* @param string $method
* @param string $url
* @param array $params
* @param array $headers
*
* @throws Exception\AuthenticationException
* @throws Exception\ApiConnectionException
*
* @return array
*/
private function _requestRaw($method, $url, $params, $headers)
private function _prepareRequest($method, $url, $params, $headers)
{
$myApiKey = $this->_apiKey;
if (!$myApiKey) {
@ -416,6 +428,24 @@ class ApiRequestor
$rawHeaders[] = $header . ': ' . $value;
}
return [$absUrl, $rawHeaders, $params, $hasFile, $myApiKey];
}
/**
* @param string $method
* @param string $url
* @param array $params
* @param array $headers
*
* @throws Exception\AuthenticationException
* @throws Exception\ApiConnectionException
*
* @return array
*/
private function _requestRaw($method, $url, $params, $headers)
{
list($absUrl, $rawHeaders, $params, $hasFile, $myApiKey) = $this->_prepareRequest($method, $url, $params, $headers);
$requestStartMs = Util\Util::currentTimeMillis();
list($rbody, $rcode, $rheaders) = $this->httpClient()->request(
@ -428,7 +458,46 @@ class ApiRequestor
if (isset($rheaders['request-id'])
&& \is_string($rheaders['request-id'])
&& \strlen($rheaders['request-id']) > 0) {
&& '' !== $rheaders['request-id']) {
self::$requestTelemetry = new RequestTelemetry(
$rheaders['request-id'],
Util\Util::currentTimeMillis() - $requestStartMs
);
}
return [$rbody, $rcode, $rheaders, $myApiKey];
}
/**
* @param string $method
* @param string $url
* @param array $params
* @param array $headers
* @param callable $readBodyChunkCallable
*
* @throws Exception\AuthenticationException
* @throws Exception\ApiConnectionException
*
* @return array
*/
private function _requestRawStreaming($method, $url, $params, $headers, $readBodyChunkCallable)
{
list($absUrl, $rawHeaders, $params, $hasFile, $myApiKey) = $this->_prepareRequest($method, $url, $params, $headers);
$requestStartMs = Util\Util::currentTimeMillis();
list($rbody, $rcode, $rheaders) = $this->streamingHttpClient()->requestStream(
$method,
$absUrl,
$rawHeaders,
$params,
$hasFile,
$readBodyChunkCallable
);
if (isset($rheaders['request-id'])
&& \is_string($rheaders['request-id'])
&& '' !== $rheaders['request-id']) {
self::$requestTelemetry = new RequestTelemetry(
$rheaders['request-id'],
Util\Util::currentTimeMillis() - $requestStartMs
@ -502,6 +571,16 @@ class ApiRequestor
self::$_httpClient = $client;
}
/**
* @static
*
* @param HttpClient\StreamingClientInterface $client
*/
public static function setStreamingHttpClient($client)
{
self::$_streamingHttpClient = $client;
}
/**
* @static
*
@ -523,4 +602,16 @@ class ApiRequestor
return self::$_httpClient;
}
/**
* @return HttpClient\StreamingClientInterface
*/
private function streamingHttpClient()
{
if (!self::$_streamingHttpClient) {
self::$_streamingHttpClient = HttpClient\CurlClient::instance();
}
return self::$_streamingHttpClient;
}
}

View File

@ -82,6 +82,8 @@ abstract class ApiResource extends StripeObject
{
// Replace dots with slashes for namespaced resources, e.g. if the object's name is
// "foo.bar", then its URL will be "/v1/foo/bars".
/** @phpstan-ignore-next-line */
$base = \str_replace('.', '/', static::OBJECT_NAME);
return "/v1/{$base}s";

View File

@ -18,7 +18,7 @@ namespace Stripe;
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property null|string|\Stripe\Charge $originating_transaction ID of the corresponding charge on the platform account, if this fee was the result of a charge using the <code>destination</code> parameter.
* @property bool $refunded Whether the fee has been fully refunded. If the fee is only partially refunded, this attribute will still be false.
* @property \Stripe\Collection $refunds A list of refunds that have been applied to the fee.
* @property \Stripe\Collection<\Stripe\StripeObject> $refunds A list of refunds that have been applied to the fee.
*/
class ApplicationFee extends ApiResource
{
@ -37,7 +37,7 @@ class ApplicationFee extends ApiResource
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Collection the list of fee refunds
* @return \Stripe\Collection<\Stripe\ApplicationFeeRefund> the list of fee refunds
*/
public static function allRefunds($id, $params = null, $opts = null)
{

View File

@ -0,0 +1,79 @@
<?php
// File generated from our OpenAPI spec
namespace Stripe\Apps;
/**
* Secret Store is an API that allows Stripe Apps developers to securely persist
* secrets for use by UI Extensions and app backends.
*
* The primary resource in Secret Store is a <code>secret</code>. Other apps can't
* view secrets created by an app. Additionally, secrets are scoped to provide
* further permission control.
*
* All Dashboard users and the app backend share <code>account</code> scoped
* secrets. Use the <code>account</code> scope for secrets that don't change
* per-user, like a third-party API key.
*
* A <code>user</code> scoped secret is accessible by the app backend and one
* specific Dashboard user. Use the <code>user</code> scope for per-user secrets
* like per-user OAuth tokens, where different users might have different
* permissions.
*
* Related guide: <a
* href="https://stripe.com/docs/stripe-apps/store-auth-data-custom-objects">Store
* data between page reloads</a>.
*
* @property string $id Unique identifier for the object.
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property null|int $expires_at The Unix timestamp for the expiry time of the secret, after which the secret deletes.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property string $name A name for the secret that's unique within the scope.
* @property null|string $payload The plaintext secret value to be stored.
* @property \Stripe\StripeObject $scope
*/
class Secret extends \Stripe\ApiResource
{
const OBJECT_NAME = 'apps.secret';
use \Stripe\ApiOperations\All;
use \Stripe\ApiOperations\Create;
/**
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Apps\Secret the deleted secret
*/
public static function deleteWhere($params = null, $opts = null)
{
$url = static::classUrl() . '/delete';
list($response, $opts) = static::_staticRequest('post', $url, $params, $opts);
$obj = \Stripe\Util\Util::convertToStripeObject($response->json, $opts);
$obj->setLastResponse($response);
return $obj;
}
/**
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Apps\Secret the finded secret
*/
public static function find($params = null, $opts = null)
{
$url = static::classUrl() . '/find';
list($response, $opts) = static::_staticRequest('get', $url, $params, $opts);
$obj = \Stripe\Util\Util::convertToStripeObject($response->json, $opts);
$obj->setLastResponse($response);
return $obj;
}
}

View File

@ -31,15 +31,5 @@ class Balance extends SingletonApiResource
{
const OBJECT_NAME = 'balance';
/**
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Balance
*/
public static function retrieve($opts = null)
{
return self::_singletonRetrieve($opts);
}
use ApiOperations\SingletonRetrieve;
}

View File

@ -23,6 +23,7 @@ namespace Stripe;
* @property null|string|\Stripe\Account $account The ID of the account that the bank account is associated with.
* @property null|string $account_holder_name The name of the person or business that owns the bank account.
* @property null|string $account_holder_type The type of entity that holds the account. This can be either <code>individual</code> or <code>company</code>.
* @property null|string $account_type The bank account type. This can only be <code>checking</code> or <code>savings</code> in most countries. In Japan, this can only be <code>futsu</code> or <code>toza</code>.
* @property null|string[] $available_payout_methods A set of available payout methods for this bank account. Only values from this set should be passed as the <code>method</code> when creating a payout.
* @property null|string $bank_name Name of the bank associated with the routing number (e.g., <code>WELLS FARGO</code>).
* @property string $country Two-letter ISO code representing the country the bank account is located in.

View File

@ -2,7 +2,7 @@
namespace Stripe;
class BaseStripeClient implements StripeClientInterface
class BaseStripeClient implements StripeClientInterface, StripeStreamingClientInterface
{
/** @var string default base URL for Stripe's API */
const DEFAULT_API_BASE = 'https://api.stripe.com';
@ -139,6 +139,25 @@ class BaseStripeClient implements StripeClientInterface
return $obj;
}
/**
* Sends a request to Stripe's API, passing chunks of the streamed response
* into a user-provided $readBodyChunkCallable callback.
*
* @param string $method the HTTP method
* @param string $path the path of the request
* @param callable $readBodyChunkCallable a function that will be called
* @param array $params the parameters of the request
* @param array|\Stripe\Util\RequestOptions $opts the special modifiers of the request
* with chunks of bytes from the body if the request is successful
*/
public function requestStream($method, $path, $readBodyChunkCallable, $params, $opts)
{
$opts = $this->defaultOpts->merge($opts, true);
$baseUrl = $opts->apiBase ?: $this->getApiBase();
$requestor = new \Stripe\ApiRequestor($this->apiKeyForRequest($opts), $baseUrl);
list($response, $opts->apiKey) = $requestor->requestStream($method, $path, $readBodyChunkCallable, $params, $opts->headers);
}
/**
* Sends a request to Stripe's API.
*
@ -163,6 +182,30 @@ class BaseStripeClient implements StripeClientInterface
return $obj;
}
/**
* Sends a request to Stripe's API.
*
* @param string $method the HTTP method
* @param string $path the path of the request
* @param array $params the parameters of the request
* @param array|\Stripe\Util\RequestOptions $opts the special modifiers of the request
*
* @return \Stripe\SearchResult of ApiResources
*/
public function requestSearchResult($method, $path, $params, $opts)
{
$obj = $this->request($method, $path, $params, $opts);
if (!($obj instanceof \Stripe\SearchResult)) {
$received_class = \get_class($obj);
$msg = "Expected to receive `Stripe\\SearchResult` object from Stripe API. Instead received `{$received_class}`.";
throw new \Stripe\Exception\UnexpectedValueException($msg);
}
$obj->setFilters($params);
return $obj;
}
/**
* @param \Stripe\Util\RequestOptions $opts
*

View File

@ -5,7 +5,7 @@ namespace Stripe;
/**
* Interface for a Stripe client.
*/
interface StripeClientInterface
interface BaseStripeClientInterface
{
/**
* Gets the API key used by the client to send requests.
@ -41,16 +41,4 @@ interface StripeClientInterface
* @return string the base URL for Stripe's Files API
*/
public function getFilesBase();
/**
* Sends a request to Stripe's API.
*
* @param string $method the HTTP method
* @param string $path the path of the request
* @param array $params the parameters of the request
* @param array|\Stripe\Util\RequestOptions $opts the special modifiers of the request
*
* @return \Stripe\StripeObject the object returned by Stripe's API
*/
public function request($method, $path, $params, $opts);
}

View File

@ -0,0 +1,33 @@
<?php
// File generated from our OpenAPI spec
namespace Stripe\BillingPortal;
/**
* A portal configuration describes the functionality and behavior of a portal
* session.
*
* @property string $id Unique identifier for the object.
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property bool $active Whether the configuration is active and can be used to create portal sessions.
* @property null|string|\Stripe\StripeObject $application ID of the Connect Application that created the configuration.
* @property \Stripe\StripeObject $business_profile
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property null|string $default_return_url The default URL to redirect customers to when they click on the portal's link to return to your website. This can be <a href="https://stripe.com/docs/api/customer_portal/sessions/create#create_portal_session-return_url">overriden</a> when creating the session.
* @property \Stripe\StripeObject $features
* @property bool $is_default Whether the configuration is the default. If <code>true</code>, this configuration can be managed in the Dashboard and portal sessions will use this configuration unless it is overriden when creating the session.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property \Stripe\StripeObject $login_page
* @property null|\Stripe\StripeObject $metadata Set of <a href="https://stripe.com/docs/api/metadata">key-value pairs</a> that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
* @property int $updated Time at which the object was last updated. Measured in seconds since the Unix epoch.
*/
class Configuration extends \Stripe\ApiResource
{
const OBJECT_NAME = 'billing_portal.configuration';
use \Stripe\ApiOperations\All;
use \Stripe\ApiOperations\Create;
use \Stripe\ApiOperations\Retrieve;
use \Stripe\ApiOperations\Update;
}

View File

@ -0,0 +1,42 @@
<?php
// File generated from our OpenAPI spec
namespace Stripe\BillingPortal;
/**
* The Billing customer portal is a Stripe-hosted UI for subscription and billing
* management.
*
* A portal configuration describes the functionality and features that you want to
* provide to your customers through the portal.
*
* A portal session describes the instantiation of the customer portal for a
* particular customer. By visiting the session's URL, the customer can manage
* their subscriptions and billing details. For security reasons, sessions are
* short-lived and will expire if the customer does not visit the URL. Create
* sessions on-demand when customers intend to manage their subscriptions and
* billing details.
*
* Learn more in the <a
* href="https://stripe.com/docs/billing/subscriptions/integrating-customer-portal">integration
* guide</a>.
*
* @property string $id Unique identifier for the object.
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property string|\Stripe\BillingPortal\Configuration $configuration The configuration used by this session, describing the features available.
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property string $customer The ID of the customer for this session.
* @property null|\Stripe\StripeObject $flow Information about a specific flow for the customer to go through.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property null|string $locale The IETF language tag of the locale Customer Portal is displayed in. If blank or auto, the customers <code>preferred_locales</code> or browsers locale is used.
* @property null|string $on_behalf_of The account for which the session was created on behalf of. When specified, only subscriptions and invoices with this <code>on_behalf_of</code> account appear in the portal. For more information, see the <a href="https://stripe.com/docs/connect/charges-transfers#on-behalf-of">docs</a>. Use the <a href="https://stripe.com/docs/api/accounts/object#account_object-settings-branding">Accounts API</a> to modify the <code>on_behalf_of</code> account's branding settings, which the portal displays.
* @property null|string $return_url The URL to redirect customers to when they click on the portal's link to return to your website.
* @property string $url The short-lived URL of the session that gives customers access to the customer portal.
*/
class Session extends \Stripe\ApiResource
{
const OBJECT_NAME = 'billing_portal.session';
use \Stripe\ApiOperations\Create;
}

View File

@ -14,6 +14,7 @@ namespace Stripe;
* @property string $id The identifier for the capability.
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property string|\Stripe\Account $account The account for which the capability enables functionality.
* @property \Stripe\StripeObject $future_requirements
* @property bool $requested Whether the capability has been requested.
* @property null|int $requested_at Time at which the capability was requested. Measured in seconds since the Unix epoch.
* @property \Stripe\StripeObject $requirements

View File

@ -33,12 +33,12 @@ namespace Stripe;
* @property null|string $dynamic_last4 (For tokenized numbers only.) The last four digits of the device account number.
* @property int $exp_month Two-digit number representing the card's expiration month.
* @property int $exp_year Four-digit number representing the card's expiration year.
* @property null|string $fingerprint Uniquely identifies this particular card number. You can use this attribute to check whether two customers whove signed up with you are using the same card number, for example. For payment methods that tokenize card information (Apple Pay, Google Pay), the tokenized number might be provided instead of the underlying card number.
* @property null|string $fingerprint <p>Uniquely identifies this particular card number. You can use this attribute to check whether two customers whove signed up with you are using the same card number, for example. For payment methods that tokenize card information (Apple Pay, Google Pay), the tokenized number might be provided instead of the underlying card number.</p><p><em>Starting May 1, 2021, card fingerprint in India for Connect will change to allow two fingerprints for the same card --- one for India and one for the rest of the world.</em></p>
* @property string $funding Card funding type. Can be <code>credit</code>, <code>debit</code>, <code>prepaid</code>, or <code>unknown</code>.
* @property string $last4 The last four digits of the card.
* @property null|\Stripe\StripeObject $metadata Set of <a href="https://stripe.com/docs/api/metadata">key-value pairs</a> that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
* @property null|string $name Cardholder name.
* @property null|string|\Stripe\Recipient $recipient The recipient that this card belongs to. This attribute will not be in the card object if the card belongs to a customer or account instead.
* @property null|string $status For external accounts, possible values are <code>new</code> and <code>errored</code>. If a transfer fails, the status is set to <code>errored</code> and transfers are stopped until account details are updated.
* @property null|string $tokenization_method If the card number is tokenized, this is the method that was used. Can be <code>android_pay</code> (includes Google Pay), <code>apple_pay</code>, <code>masterpass</code>, <code>visa_checkout</code>, or null.
*/
class Card extends ApiResource
@ -91,12 +91,8 @@ class Card extends ApiResource
$base = Account::classUrl();
$parent = $this['account'];
$path = 'external_accounts';
} elseif ($this['recipient']) {
$base = Recipient::classUrl();
$parent = $this['recipient'];
$path = 'cards';
} else {
$msg = 'Cards cannot be accessed without a customer ID, account ID or recipient ID.';
$msg = 'Cards cannot be accessed without a customer ID, or account ID.';
throw new Exception\UnexpectedValueException($msg);
}

View File

@ -0,0 +1,66 @@
<?php
// File generated from our OpenAPI spec
namespace Stripe;
/**
* A customer's <code>Cash balance</code> represents real funds. Customers can add
* funds to their cash balance by sending a bank transfer. These funds can be used
* for payment and can eventually be paid out to your bank account.
*
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property null|\Stripe\StripeObject $available A hash of all cash balances available to this customer. You cannot delete a customer with any cash balances, even if the balance is 0. Amounts are represented in the <a href="https://stripe.com/docs/currencies#zero-decimal">smallest currency unit</a>.
* @property string $customer The ID of the customer whose cash balance this object represents.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property \Stripe\StripeObject $settings
*/
class CashBalance extends ApiResource
{
const OBJECT_NAME = 'cash_balance';
/**
* @return string the API URL for this balance transaction
*/
public function instanceUrl()
{
$customer = $this['customer'];
$customer = Util\Util::utf8($customer);
$base = Customer::classUrl();
$customerExtn = \urlencode($customer);
return "{$base}/{$customerExtn}/cash_balance";
}
/**
* @param array|string $_id
* @param null|array|string $_opts
*
* @throws \Stripe\Exception\BadMethodCallException
*/
public static function retrieve($_id, $_opts = null)
{
$msg = 'Customer Cash Balance cannot be retrieved without a ' .
'customer ID. Retrieve a Customer Cash Balance using ' .
"`Customer::retrieveCashBalance('customer_id')`.";
throw new Exception\BadMethodCallException($msg);
}
/**
* @param string $_id
* @param null|array $_params
* @param null|array|string $_options
*
* @throws \Stripe\Exception\BadMethodCallException
*/
public static function update($_id, $_params = null, $_options = null)
{
$msg = 'Customer Cash Balance cannot be updated without a ' .
'customer ID. Retrieve a Customer Cash Balance using ' .
"`Customer::updateCashBalance('customer_id')`.";
throw new Exception\BadMethodCallException($msg);
}
}

View File

@ -15,12 +15,14 @@ namespace Stripe;
*
* @property string $id Unique identifier for the object.
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property \Stripe\StripeObject $alternate_statement_descriptors
* @property int $amount Amount intended to be collected by this payment. A positive integer representing how much to charge in the <a href="https://stripe.com/docs/currencies#zero-decimal">smallest currency unit</a> (e.g., 100 cents to charge $1.00 or 100 to charge ¥100, a zero-decimal currency). The minimum amount is $0.50 US or <a href="https://stripe.com/docs/currencies#minimum-and-maximum-charge-amounts">equivalent in charge currency</a>. The amount value supports up to eight digits (e.g., a value of 99999999 for a USD charge of $999,999.99).
* @property int $amount_captured Amount in %s captured (can be less than the amount attribute on the charge if a partial capture was made).
* @property int $amount_refunded Amount in %s refunded (can be less than the amount attribute on the charge if a partial refund was issued).
* @property null|string|\Stripe\StripeObject $application ID of the Connect application that created the charge.
* @property null|string|\Stripe\ApplicationFee $application_fee The application fee (if any) for the charge. <a href="https://stripe.com/docs/connect/direct-charges#collecting-fees">See the Connect documentation</a> for details.
* @property null|int $application_fee_amount The amount of the application fee (if any) requested for the charge. <a href="https://stripe.com/docs/connect/direct-charges#collecting-fees">See the Connect documentation</a> for details.
* @property string $authorization_code Authorization code on the charge.
* @property null|string|\Stripe\BalanceTransaction $balance_transaction ID of the balance transaction that describes the impact of this charge on your account balance (not including refunds or disputes).
* @property \Stripe\StripeObject $billing_details
* @property null|string $calculated_statement_descriptor The full statement descriptor that is passed to card networks, and that is displayed on your customers' credit card and bank statements. Allows you to see what the statement descriptor looks like after the static and dynamic portions are combined.
@ -32,27 +34,29 @@ namespace Stripe;
* @property null|string|\Stripe\Account $destination ID of an existing, connected Stripe account to transfer funds to if <code>transfer_data</code> was specified in the charge request.
* @property null|string|\Stripe\Dispute $dispute Details about the dispute if the charge has been disputed.
* @property bool $disputed Whether the charge has been disputed.
* @property null|string $failure_code Error code explaining reason for charge failure if available (see <a href="https://stripe.com/docs/api#errors">the errors section</a> for a list of codes).
* @property null|string|\Stripe\BalanceTransaction $failure_balance_transaction ID of the balance transaction that describes the reversal of the balance on your account due to payment failure.
* @property null|string $failure_code Error code explaining reason for charge failure if available (see <a href="https://stripe.com/docs/error-codes">the errors section</a> for a list of codes).
* @property null|string $failure_message Message to user further explaining reason for charge failure if available.
* @property null|\Stripe\StripeObject $fraud_details Information on fraud assessments for the charge.
* @property null|string|\Stripe\Invoice $invoice ID of the invoice this charge is for if one exists.
* @property \Stripe\StripeObject $level3
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property \Stripe\StripeObject $metadata Set of <a href="https://stripe.com/docs/api/metadata">key-value pairs</a> that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
* @property null|string|\Stripe\Account $on_behalf_of The account (if any) the charge was made on behalf of without triggering an automatic transfer. See the <a href="https://stripe.com/docs/connect/charges-transfers">Connect documentation</a> for details.
* @property null|string|\Stripe\Order $order ID of the order this charge is for if one exists.
* @property null|\Stripe\StripeObject $outcome Details about whether the payment was accepted, and why. See <a href="https://stripe.com/docs/declines">understanding declines</a> for details.
* @property bool $paid <code>true</code> if the charge succeeded, or was successfully authorized for later capture.
* @property null|string|\Stripe\PaymentIntent $payment_intent ID of the PaymentIntent associated with this charge, if one exists.
* @property null|string $payment_method ID of the payment method used in this charge.
* @property null|\Stripe\StripeObject $payment_method_details Details about the payment method at the time of the transaction.
* @property \Stripe\StripeObject $radar_options Options to configure Radar. See <a href="https://stripe.com/docs/radar/radar-session">Radar Session</a> for more information.
* @property null|string $receipt_email This is the email address that the receipt for this charge was sent to.
* @property null|string $receipt_number This is the transaction number that appears on email receipts sent for this charge. This attribute will be <code>null</code> until a receipt has been sent.
* @property null|string $receipt_url This is the URL to view the receipt for this charge. The receipt is kept up-to-date to the latest state of the charge, including any refunds. If the charge is for an Invoice, the receipt will be stylized as an Invoice receipt.
* @property bool $refunded Whether the charge has been fully refunded. If the charge is only partially refunded, this attribute will still be false.
* @property \Stripe\Collection $refunds A list of refunds that have been applied to the charge.
* @property null|\Stripe\Collection<\Stripe\Refund> $refunds A list of refunds that have been applied to the charge.
* @property null|string|\Stripe\Review $review ID of the review associated with this charge if one exists.
* @property null|\Stripe\StripeObject $shipping Shipping information for the charge.
* @property null|\Stripe\Account|\Stripe\AlipayAccount|\Stripe\BankAccount|\Stripe\BitcoinReceiver|\Stripe\Card|\Stripe\Source $source This is a legacy field that will be removed in the future. It contains the Source, Card, or BankAccount object used for the charge. For details about the payment method used for this charge, refer to <code>payment_method</code> or <code>payment_method_details</code> instead.
* @property null|\Stripe\Account|\Stripe\BankAccount|\Stripe\Card|\Stripe\Source $source This is a legacy field that will be removed in the future. It contains the Source, Card, or BankAccount object used for the charge. For details about the payment method used for this charge, refer to <code>payment_method</code> or <code>payment_method_details</code> instead.
* @property null|string|\Stripe\Transfer $source_transfer The transfer ID which created this charge. Only present if the charge came from another Stripe account. <a href="https://stripe.com/docs/connect/destination-charges">See the Connect documentation</a> for details.
* @property null|string $statement_descriptor For card charges, use <code>statement_descriptor_suffix</code> instead. Otherwise, you can use this value as the complete description of a charge on your customers statements. Must contain at least one letter, maximum 22 characters.
* @property null|string $statement_descriptor_suffix Provides information about the charge that customers see on their statements. Concatenated with the prefix (shortened descriptor) or statement descriptor thats set on the account to form the complete statement descriptor. Maximum 22 characters for the concatenated descriptor.
@ -68,6 +72,7 @@ class Charge extends ApiResource
use ApiOperations\All;
use ApiOperations\Create;
use ApiOperations\Retrieve;
use ApiOperations\Search;
use ApiOperations\Update;
const STATUS_FAILED = 'failed';
@ -133,7 +138,7 @@ class Charge extends ApiResource
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return Charge the captured charge
* @return \Stripe\Charge the captured charge
*/
public function capture($params = null, $opts = null)
{
@ -143,4 +148,19 @@ class Charge extends ApiResource
return $this;
}
/**
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\SearchResult<Charge> the charge search results
*/
public static function search($params = null, $opts = null)
{
$url = '/v1/charges/search';
return self::_searchResource($url, $params, $opts);
}
}

View File

@ -7,8 +7,9 @@ namespace Stripe\Checkout;
/**
* A Checkout Session represents your customer's session as they pay for one-time
* purchases or subscriptions through <a
* href="https://stripe.com/docs/payments/checkout">Checkout</a>. We recommend
* creating a new Session each time your customer attempts to pay.
* href="https://stripe.com/docs/payments/checkout">Checkout</a> or <a
* href="https://stripe.com/docs/payments/payment-links">Payment Links</a>. We
* recommend creating a new Session each time your customer attempts to pay.
*
* Once payment is successful, the Checkout Session will contain a reference to the
* <a href="https://stripe.com/docs/api/customers">Customer</a>, and either the
@ -19,36 +20,56 @@ namespace Stripe\Checkout;
* You can create a Checkout Session on your server and pass its ID to the client
* to begin Checkout.
*
* Related guide: <a href="https://stripe.com/docs/payments/checkout/api">Checkout
* Server Quickstart</a>.
* Related guide: <a href="https://stripe.com/docs/checkout/quickstart">Checkout
* Quickstart</a>.
*
* @property string $id Unique identifier for the object. Used to pass to <code>redirectToCheckout</code> in Stripe.js.
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property null|\Stripe\StripeObject $after_expiration When set, provides configuration for actions to take if this Checkout Session expires.
* @property null|bool $allow_promotion_codes Enables user redeemable promotion codes.
* @property null|int $amount_subtotal Total of all items before discounts or taxes are applied.
* @property null|int $amount_total Total of all items after discounts and taxes are applied.
* @property \Stripe\StripeObject $automatic_tax
* @property null|string $billing_address_collection Describes whether Checkout should collect the customer's billing address.
* @property string $cancel_url The URL the customer will be directed to if they decide to cancel payment and return to your website.
* @property null|string $cancel_url If set, Checkout displays a back button and customers will be directed to this URL if they decide to cancel payment and return to your website.
* @property null|string $client_reference_id A unique string to reference the Checkout Session. This can be a customer ID, a cart ID, or similar, and can be used to reconcile the Session with your internal systems.
* @property null|\Stripe\StripeObject $consent Results of <code>consent_collection</code> for this session.
* @property null|\Stripe\StripeObject $consent_collection When set, provides configuration for the Checkout Session to gather active consent from customers.
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property null|string $currency Three-letter <a href="https://www.iso.org/iso-4217-currency-codes.html">ISO currency code</a>, in lowercase. Must be a <a href="https://stripe.com/docs/currencies">supported currency</a>.
* @property \Stripe\StripeObject $custom_text
* @property null|string|\Stripe\Customer $customer The ID of the customer for this Session. For Checkout Sessions in <code>payment</code> or <code>subscription</code> mode, Checkout will create a new customer object based on information provided during the payment flow unless an existing customer was provided when the Session was created.
* @property null|\Stripe\StripeObject $customer_details The customer details including the customer's tax exempt status and the customer's tax IDs.
* @property null|string $customer_creation Configure whether a Checkout Session creates a Customer when the Checkout Session completes.
* @property null|\Stripe\StripeObject $customer_details The customer details including the customer's tax exempt status and the customer's tax IDs. Only the customer's email is present on Sessions in <code>setup</code> mode.
* @property null|string $customer_email If provided, this value will be used when the Customer object is created. If not provided, customers will be asked to enter their email address. Use this parameter to prefill customer data if you already have an email on file. To access information about the customer once the payment flow is complete, use the <code>customer</code> attribute.
* @property \Stripe\Collection $line_items The line items purchased by the customer.
* @property int $expires_at The timestamp at which the Checkout Session will expire.
* @property null|string|\Stripe\Invoice $invoice ID of the invoice created by the Checkout Session, if it exists.
* @property null|\Stripe\StripeObject $invoice_creation Details on the state of invoice creation for the Checkout Session.
* @property \Stripe\Collection<\Stripe\LineItem> $line_items The line items purchased by the customer.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property null|string $locale The IETF language tag of the locale Checkout is displayed in. If blank or <code>auto</code>, the browser's locale is used.
* @property null|\Stripe\StripeObject $metadata Set of <a href="https://stripe.com/docs/api/metadata">key-value pairs</a> that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
* @property string $mode The mode of the Checkout Session.
* @property null|string|\Stripe\PaymentIntent $payment_intent The ID of the PaymentIntent for Checkout Sessions in <code>payment</code> mode.
* @property null|string|\Stripe\PaymentLink $payment_link The ID of the Payment Link that created this Session.
* @property null|string $payment_method_collection Configure whether a Checkout Session should collect a payment method.
* @property null|\Stripe\StripeObject $payment_method_options Payment-method-specific configuration for the PaymentIntent or SetupIntent of this CheckoutSession.
* @property string[] $payment_method_types A list of the types of payment methods (e.g. card) this Checkout Session is allowed to accept.
* @property string $payment_status The payment status of the Checkout Session, one of <code>paid</code>, <code>unpaid</code>, or <code>no_payment_required</code>. You can use this value to decide when to fulfill your customer's order.
* @property \Stripe\StripeObject $phone_number_collection
* @property null|string $recovered_from The ID of the original expired Checkout Session that triggered the recovery flow.
* @property null|string|\Stripe\SetupIntent $setup_intent The ID of the SetupIntent for Checkout Sessions in <code>setup</code> mode.
* @property null|\Stripe\StripeObject $shipping Shipping information for this Checkout Session.
* @property null|\Stripe\StripeObject $shipping_address_collection When set, provides configuration for Checkout to collect a shipping address from a customer.
* @property null|\Stripe\StripeObject $shipping_cost The details of the customer cost of shipping, including the customer chosen ShippingRate.
* @property null|\Stripe\StripeObject $shipping_details Shipping information for this Checkout Session.
* @property \Stripe\StripeObject[] $shipping_options The shipping rate options applied to this Session.
* @property null|string $status The status of the Checkout Session, one of <code>open</code>, <code>complete</code>, or <code>expired</code>.
* @property null|string $submit_type Describes the type of transaction being performed by Checkout in order to customize relevant text on the page, such as the submit button. <code>submit_type</code> can only be specified on Checkout Sessions in <code>payment</code> mode, but not Checkout Sessions in <code>subscription</code> or <code>setup</code> mode.
* @property null|string|\Stripe\Subscription $subscription The ID of the subscription for Checkout Sessions in <code>subscription</code> mode.
* @property string $success_url The URL the customer will be directed to after the payment or subscription creation is successful.
* @property \Stripe\StripeObject $tax_id_collection
* @property null|\Stripe\StripeObject $total_details Tax and discount details for the computed total amount.
* @property null|string $url The URL to the Checkout Session. Redirect customers to this URL to take them to Checkout. If youre using <a href="https://stripe.com/docs/payments/checkout/custom-domains">Custom Domains</a>, the URL will use your subdomain. Otherwise, itll use <code>checkout.stripe.com.</code> This value is only present when the session is active.
*/
class Session extends \Stripe\ApiResource
{
@ -56,34 +77,67 @@ class Session extends \Stripe\ApiResource
use \Stripe\ApiOperations\All;
use \Stripe\ApiOperations\Create;
use \Stripe\ApiOperations\NestedResource;
use \Stripe\ApiOperations\Retrieve;
const BILLING_ADDRESS_COLLECTION_AUTO = 'auto';
const BILLING_ADDRESS_COLLECTION_REQUIRED = 'required';
const CUSTOMER_CREATION_ALWAYS = 'always';
const CUSTOMER_CREATION_IF_REQUIRED = 'if_required';
const MODE_PAYMENT = 'payment';
const MODE_SETUP = 'setup';
const MODE_SUBSCRIPTION = 'subscription';
const PAYMENT_METHOD_COLLECTION_ALWAYS = 'always';
const PAYMENT_METHOD_COLLECTION_IF_REQUIRED = 'if_required';
const PAYMENT_STATUS_NO_PAYMENT_REQUIRED = 'no_payment_required';
const PAYMENT_STATUS_PAID = 'paid';
const PAYMENT_STATUS_UNPAID = 'unpaid';
const STATUS_COMPLETE = 'complete';
const STATUS_EXPIRED = 'expired';
const STATUS_OPEN = 'open';
const SUBMIT_TYPE_AUTO = 'auto';
const SUBMIT_TYPE_BOOK = 'book';
const SUBMIT_TYPE_DONATE = 'donate';
const SUBMIT_TYPE_PAY = 'pay';
const PATH_LINE_ITEMS = '/line_items';
/**
* @param string $id the ID of the session on which to retrieve the items
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Collection the list of items
* @return \Stripe\Checkout\Session the expired session
*/
public function expire($params = null, $opts = null)
{
$url = $this->instanceUrl() . '/expire';
list($response, $opts) = $this->_request('post', $url, $params, $opts);
$this->refreshFrom($response, $opts);
return $this;
}
/**
* @param string $id
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Collection<\Stripe\LineItem> list of LineItems
*/
public static function allLineItems($id, $params = null, $opts = null)
{
return self::_allNestedResources($id, static::PATH_LINE_ITEMS, $params, $opts);
$url = static::resourceUrl($id) . '/line_items';
list($response, $opts) = static::_staticRequest('get', $url, $params, $opts);
$obj = \Stripe\Util\Util::convertToStripeObject($response->json, $opts);
$obj->setLastResponse($response);
return $obj;
}
}

View File

@ -5,10 +5,13 @@ namespace Stripe;
/**
* Class Collection.
*
* @template TStripeObject of StripeObject
* @template-implements \IteratorAggregate<TStripeObject>
*
* @property string $object
* @property string $url
* @property bool $has_more
* @property \Stripe\StripeObject[] $data
* @property TStripeObject[] $data
*/
class Collection extends StripeObject implements \Countable, \IteratorAggregate
{
@ -47,6 +50,10 @@ class Collection extends StripeObject implements \Countable, \IteratorAggregate
$this->filters = $filters;
}
/**
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet($k)
{
if (\is_string($k)) {
@ -60,6 +67,14 @@ class Collection extends StripeObject implements \Countable, \IteratorAggregate
throw new Exception\InvalidArgumentException($msg);
}
/**
* @param null|array $params
* @param null|array|string $opts
*
* @throws Exception\ApiErrorException
*
* @return Collection<TStripeObject>
*/
public function all($params = null, $opts = null)
{
self::_validateParams($params);
@ -77,6 +92,14 @@ class Collection extends StripeObject implements \Countable, \IteratorAggregate
return $obj;
}
/**
* @param null|array $params
* @param null|array|string $opts
*
* @throws Exception\ApiErrorException
*
* @return TStripeObject
*/
public function create($params = null, $opts = null)
{
self::_validateParams($params);
@ -87,6 +110,15 @@ class Collection extends StripeObject implements \Countable, \IteratorAggregate
return Util\Util::convertToStripeObject($response, $opts);
}
/**
* @param string $id
* @param null|array $params
* @param null|array|string $opts
*
* @throws Exception\ApiErrorException
*
* @return TStripeObject
*/
public function retrieve($id, $params = null, $opts = null)
{
self::_validateParams($params);
@ -107,6 +139,7 @@ class Collection extends StripeObject implements \Countable, \IteratorAggregate
/**
* @return int the number of objects in the current page
*/
#[\ReturnTypeWillChange]
public function count()
{
return \count($this->data);
@ -116,6 +149,7 @@ class Collection extends StripeObject implements \Countable, \IteratorAggregate
* @return \ArrayIterator an iterator that can be used to iterate
* across objects in the current page
*/
#[\ReturnTypeWillChange]
public function getIterator()
{
return new \ArrayIterator($this->data);
@ -131,7 +165,7 @@ class Collection extends StripeObject implements \Countable, \IteratorAggregate
}
/**
* @return \Generator|StripeObject[] A generator that can be used to
* @return \Generator|TStripeObject[] A generator that can be used to
* iterate across all objects across all pages. As page boundaries are
* encountered, the next page will be fetched automatically for
* continued iteration.
@ -194,7 +228,7 @@ class Collection extends StripeObject implements \Countable, \IteratorAggregate
* @param null|array $params
* @param null|array|string $opts
*
* @return Collection
* @return Collection<TStripeObject>
*/
public function nextPage($params = null, $opts = null)
{
@ -222,7 +256,7 @@ class Collection extends StripeObject implements \Countable, \IteratorAggregate
* @param null|array $params
* @param null|array|string $opts
*
* @return Collection
* @return Collection<TStripeObject>
*/
public function previousPage($params = null, $opts = null)
{
@ -244,7 +278,7 @@ class Collection extends StripeObject implements \Countable, \IteratorAggregate
/**
* Gets the first item from the current page. Returns `null` if the current page is empty.
*
* @return null|\Stripe\StripeObject
* @return null|TStripeObject
*/
public function first()
{
@ -254,7 +288,7 @@ class Collection extends StripeObject implements \Countable, \IteratorAggregate
/**
* Gets the last item from the current page. Returns `null` if the current page is empty.
*
* @return null|\Stripe\StripeObject
* @return null|TStripeObject
*/
public function last()
{

View File

@ -7,10 +7,13 @@ namespace Stripe;
/**
* A coupon contains information about a percent-off or amount-off discount you
* might want to apply to a customer. Coupons may be applied to <a
* href="https://stripe.com/docs/api#invoices">invoices</a> or <a
* href="https://stripe.com/docs/api#create_order-coupon">orders</a>. Coupons do
* not work with conventional one-off <a
* href="https://stripe.com/docs/api#create_charge">charges</a>.
* href="https://stripe.com/docs/api#subscriptions">subscriptions</a>, <a
* href="https://stripe.com/docs/api#invoices">invoices</a>, <a
* href="https://stripe.com/docs/api/checkout/sessions">checkout sessions</a>, <a
* href="https://stripe.com/docs/api#quotes">quotes</a>, and more. Coupons do not
* work with conventional one-off <a
* href="https://stripe.com/docs/api#create_charge">charges</a> or <a
* href="https://stripe.com/docs/api/payment_intents">payment intents</a>.
*
* @property string $id Unique identifier for the object.
* @property string $object String representing the object's type. Objects of the same type share the same value.
@ -18,6 +21,7 @@ namespace Stripe;
* @property \Stripe\StripeObject $applies_to
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property null|string $currency If <code>amount_off</code> has been set, the three-letter <a href="https://stripe.com/docs/currencies">ISO code for the currency</a> of the amount to take off.
* @property \Stripe\StripeObject $currency_options Coupons defined in each available currency option. Each key must be a three-letter <a href="https://www.iso.org/iso-4217-currency-codes.html">ISO currency code</a> and a <a href="https://stripe.com/docs/currencies">supported currency</a>.
* @property string $duration One of <code>forever</code>, <code>once</code>, and <code>repeating</code>. Describes how long a customer who applies this coupon will get the discount.
* @property null|int $duration_in_months If <code>duration</code> is <code>repeating</code>, the number of months the coupon applies. Null if coupon <code>duration</code> is <code>forever</code> or <code>once</code>.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.

View File

@ -14,6 +14,7 @@ namespace Stripe;
* @property string $id Unique identifier for the object.
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property int $amount The integer amount in %s representing the total amount of the credit note, including tax.
* @property int $amount_shipping This is the sum of all the shipping amounts.
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property string $currency Three-letter <a href="https://www.iso.org/iso-4217-currency-codes.html">ISO currency code</a>, in lowercase. Must be a <a href="https://stripe.com/docs/currencies">supported currency</a>.
* @property string|\Stripe\Customer $customer ID of the customer.
@ -21,7 +22,7 @@ namespace Stripe;
* @property int $discount_amount The integer amount in %s representing the total amount of discount that was credited.
* @property \Stripe\StripeObject[] $discount_amounts The aggregate amounts calculated per discount for all line items.
* @property string|\Stripe\Invoice $invoice ID of the invoice.
* @property \Stripe\Collection $lines Line items that make up the credit note
* @property \Stripe\Collection<\Stripe\CreditNoteLineItem> $lines Line items that make up the credit note
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property null|string $memo Customer-facing text that appears on the credit note PDF.
* @property null|\Stripe\StripeObject $metadata Set of <a href="https://stripe.com/docs/api/metadata">key-value pairs</a> that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
@ -30,10 +31,13 @@ namespace Stripe;
* @property string $pdf The link to download the PDF of the credit note.
* @property null|string $reason Reason for issuing this credit note, one of <code>duplicate</code>, <code>fraudulent</code>, <code>order_change</code>, or <code>product_unsatisfactory</code>
* @property null|string|\Stripe\Refund $refund Refund related to this credit note.
* @property null|\Stripe\StripeObject $shipping_cost The details of the cost of shipping, including the ShippingRate applied to the invoice.
* @property string $status Status of this credit note, one of <code>issued</code> or <code>void</code>. Learn more about <a href="https://stripe.com/docs/billing/invoices/credit-notes#voiding">voiding credit notes</a>.
* @property int $subtotal The integer amount in %s representing the amount of the credit note, excluding tax and invoice level discounts.
* @property int $subtotal The integer amount in %s representing the amount of the credit note, excluding exclusive tax and invoice level discounts.
* @property null|int $subtotal_excluding_tax The integer amount in %s representing the amount of the credit note, excluding all tax and invoice level discounts.
* @property \Stripe\StripeObject[] $tax_amounts The aggregate amounts calculated per tax rate for all line items.
* @property int $total The integer amount in %s representing the total amount of the credit note, including tax and all discount.
* @property null|int $total_excluding_tax The integer amount in %s representing the total amount of the credit note, excluding tax, but including discounts.
* @property string $type Type of this credit note, one of <code>pre_payment</code> or <code>post_payment</code>. A <code>pre_payment</code> credit note means it was issued when the invoice was open. A <code>post_payment</code> credit note means it was issued when the invoice was paid.
* @property null|int $voided_at The time that the credit note was voided.
*/
@ -70,7 +74,7 @@ class CreditNote extends ApiResource
{
$url = static::classUrl() . '/preview';
list($response, $opts) = static::_staticRequest('get', $url, $params, $opts);
$obj = Util\Util::convertToStripeObject($response->json, $opts);
$obj = \Stripe\Util\Util::convertToStripeObject($response->json, $opts);
$obj->setLastResponse($response);
return $obj;
@ -82,7 +86,25 @@ class CreditNote extends ApiResource
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return CreditNote the voided credit note
* @return \Stripe\Collection<\Stripe\CreditNoteLineItem> list of CreditNoteLineItems
*/
public static function previewLines($params = null, $opts = null)
{
$url = static::classUrl() . '/preview/lines';
list($response, $opts) = static::_staticRequest('get', $url, $params, $opts);
$obj = \Stripe\Util\Util::convertToStripeObject($response->json, $opts);
$obj->setLastResponse($response);
return $obj;
}
/**
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\CreditNote the voided credit note
*/
public function voidCreditNote($params = null, $opts = null)
{
@ -102,7 +124,7 @@ class CreditNote extends ApiResource
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Collection the list of credit note line items
* @return \Stripe\Collection<\Stripe\CreditNoteLineItem> the list of credit note line items
*/
public static function allLines($id, $params = null, $opts = null)
{

View File

@ -8,6 +8,7 @@ namespace Stripe;
* @property string $id Unique identifier for the object.
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property int $amount The integer amount in %s representing the gross amount being credited for this line item, excluding (exclusive) tax and discounts.
* @property null|int $amount_excluding_tax The integer amount in %s representing the amount being credited for this line item, excluding all tax and discounts.
* @property null|string $description Description of the item being credited.
* @property int $discount_amount The integer amount in %s representing the discount being credited for this line item.
* @property \Stripe\StripeObject[] $discount_amounts The amount of discount calculated per discount for this line item
@ -19,6 +20,7 @@ namespace Stripe;
* @property string $type The type of the credit note line item, one of <code>invoice_line_item</code> or <code>custom_line_item</code>. When the type is <code>invoice_line_item</code> there is an additional <code>invoice_line_item</code> property on the resource the value of which is the id of the credited line item on the invoice.
* @property null|int $unit_amount The cost of each unit of product being credited.
* @property null|string $unit_amount_decimal Same as <code>unit_amount</code>, but contains a decimal value with at most 12 decimal places.
* @property null|string $unit_amount_excluding_tax The amount in %s representing the unit amount being credited for this line item, excluding all tax and discounts.
*/
class CreditNoteLineItem extends ApiResource
{

View File

@ -5,10 +5,8 @@
namespace Stripe;
/**
* <code>Customer</code> objects allow you to perform recurring charges, and to
* track multiple charges, that are associated with the same customer. The API
* allows you to create, delete, and update your customers. You can retrieve
* individual customers as well as a list of all your customers.
* This object represents a customer of your business. It lets you create recurring
* charges and track payments that belong to the same customer.
*
* Related guide: <a
* href="https://stripe.com/docs/payments/save-during-payment">Save a card during
@ -18,13 +16,15 @@ namespace Stripe;
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property null|\Stripe\StripeObject $address The customer's address.
* @property int $balance Current balance, if any, being stored on the customer. If negative, the customer has credit to apply to their next invoice. If positive, the customer has an amount owed that will be added to their next invoice. The balance does not refer to any unpaid invoices; it solely takes into account amounts that have yet to be successfully applied to any invoice. This balance is only taken into account as invoices are finalized.
* @property null|\Stripe\CashBalance $cash_balance The current funds being held by Stripe on behalf of the customer. These funds can be applied towards payment intents with source &quot;cash_balance&quot;. The settings[reconciliation_mode] field describes whether these funds are applied to such payment intents manually or automatically.
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property null|string $currency Three-letter <a href="https://stripe.com/docs/currencies">ISO code for the currency</a> the customer can be charged in for recurring billing purposes.
* @property null|string|\Stripe\Account|\Stripe\AlipayAccount|\Stripe\BankAccount|\Stripe\BitcoinReceiver|\Stripe\Card|\Stripe\Source $default_source <p>ID of the default payment source for the customer.</p><p>If you are using payment methods created via the PaymentMethods API, see the <a href="https://stripe.com/docs/api/customers/object#customer_object-invoice_settings-default_payment_method">invoice_settings.default_payment_method</a> field instead.</p>
* @property null|string|\Stripe\Account|\Stripe\BankAccount|\Stripe\Card|\Stripe\Source $default_source <p>ID of the default payment source for the customer.</p><p>If you are using payment methods created via the PaymentMethods API, see the <a href="https://stripe.com/docs/api/customers/object#customer_object-invoice_settings-default_payment_method">invoice_settings.default_payment_method</a> field instead.</p>
* @property null|bool $delinquent <p>When the customer's latest invoice is billed by charging automatically, <code>delinquent</code> is <code>true</code> if the invoice's latest charge failed. When the customer's latest invoice is billed by sending an invoice, <code>delinquent</code> is <code>true</code> if the invoice isn't paid by its due date.</p><p>If an invoice is marked uncollectible by <a href="https://stripe.com/docs/billing/automatic-collection">dunning</a>, <code>delinquent</code> doesn't get reset to <code>false</code>.</p>
* @property null|string $description An arbitrary string attached to the object. Often useful for displaying to users.
* @property null|\Stripe\Discount $discount Describes the current discount active on the customer, if there is one.
* @property null|string $email The customer's email address.
* @property \Stripe\StripeObject $invoice_credit_balance The current multi-currency balances, if any, being stored on the customer. If positive in a currency, the customer has a credit to apply to their next invoice denominated in that currency. If negative, the customer has an amount owed that will be added to their next invoice denominated in that currency. These balances do not refer to any unpaid invoices. They solely track amounts that have yet to be successfully applied to any invoice. A balance in a particular currency is only applied to any invoice as an invoice in that currency is finalized.
* @property null|string $invoice_prefix The prefix for the customer used to generate unique invoice numbers.
* @property \Stripe\StripeObject $invoice_settings
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
@ -34,10 +34,12 @@ namespace Stripe;
* @property null|string $phone The customer's phone number.
* @property null|string[] $preferred_locales The customer's preferred locales (languages), ordered by preference.
* @property null|\Stripe\StripeObject $shipping Mailing and shipping address for the customer. Appears on invoices emailed to this customer.
* @property \Stripe\Collection $sources The customer's payment sources, if any.
* @property \Stripe\Collection $subscriptions The customer's current subscriptions, if any.
* @property \Stripe\Collection<\Stripe\Account|\Stripe\BankAccount|\Stripe\Card|\Stripe\Source> $sources The customer's payment sources, if any.
* @property \Stripe\Collection<\Stripe\Subscription> $subscriptions The customer's current subscriptions, if any.
* @property \Stripe\StripeObject $tax
* @property null|string $tax_exempt Describes the customer's tax exemption status. One of <code>none</code>, <code>exempt</code>, or <code>reverse</code>. When set to <code>reverse</code>, invoice and receipt PDFs include the text <strong>&quot;Reverse charge&quot;</strong>.
* @property \Stripe\Collection $tax_ids The customer's tax IDs.
* @property \Stripe\Collection<\Stripe\TaxId> $tax_ids The customer's tax IDs.
* @property null|string|\Stripe\TestHelpers\TestClock $test_clock ID of the test clock this customer belongs to.
*/
class Customer extends ApiResource
{
@ -48,6 +50,7 @@ class Customer extends ApiResource
use ApiOperations\Delete;
use ApiOperations\NestedResource;
use ApiOperations\Retrieve;
use ApiOperations\Search;
use ApiOperations\Update;
const TAX_EXEMPT_EXEMPT = 'exempt';
@ -77,8 +80,94 @@ class Customer extends ApiResource
$url = $this->instanceUrl() . '/discount';
list($response, $opts) = $this->_request('delete', $url, $params, $opts);
$this->refreshFrom(['discount' => null], $opts, true);
return $this;
}
/**
* @param string $id
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Collection<\Stripe\PaymentMethod> list of PaymentMethods
*/
public static function allPaymentMethods($id, $params = null, $opts = null)
{
$url = static::resourceUrl($id) . '/payment_methods';
list($response, $opts) = static::_staticRequest('get', $url, $params, $opts);
$obj = \Stripe\Util\Util::convertToStripeObject($response->json, $opts);
$obj->setLastResponse($response);
return $obj;
}
/**
* @param string $payment_method
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Customer the retrieved customer
*/
public function retrievePaymentMethod($payment_method, $params = null, $opts = null)
{
$url = $this->instanceUrl() . '/payment_methods/' . $payment_method;
list($response, $opts) = $this->_request('get', $url, $params, $opts);
$obj = \Stripe\Util\Util::convertToStripeObject($response, $opts);
$obj->setLastResponse($response);
return $obj;
}
/**
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\SearchResult<Customer> the customer search results
*/
public static function search($params = null, $opts = null)
{
$url = '/v1/customers/search';
return self::_searchResource($url, $params, $opts);
}
const PATH_CASH_BALANCE = '/cash_balance';
/**
* @param string $id the ID of the customer to which the cash balance belongs
* @param null|array $params
* @param null|array|string $opts
* @param mixed $cashBalanceId
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\CashBalance
*/
public static function retrieveCashBalance($id, $cashBalanceId, $params = null, $opts = null)
{
return self::_retrieveNestedResource($id, static::PATH_CASH_BALANCE, $params, $opts);
}
/**
* @param string $id the ID of the customer to which the cash balance belongs
* @param null|array $params
* @param null|array|string $opts
* @param mixed $cashBalanceId
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\CashBalance
*/
public static function updateCashBalance($id, $cashBalanceId, $params = null, $opts = null)
{
return self::_updateNestedResource($id, static::PATH_CASH_BALANCE, $params, $opts);
}
const PATH_BALANCE_TRANSACTIONS = '/balance_transactions';
/**
@ -88,7 +177,7 @@ class Customer extends ApiResource
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Collection the list of customer balance transactions
* @return \Stripe\Collection<\Stripe\CustomerBalanceTransaction> the list of customer balance transactions
*/
public static function allBalanceTransactions($id, $params = null, $opts = null)
{
@ -138,7 +227,36 @@ class Customer extends ApiResource
{
return self::_updateNestedResource($id, static::PATH_BALANCE_TRANSACTIONS, $balanceTransactionId, $params, $opts);
}
const PATH_CASH_BALANCE_TRANSACTIONS = '/cash_balance_transactions';
/**
* @param string $id the ID of the customer on which to retrieve the customer cash balance transactions
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Collection<\Stripe\CustomerCashBalanceTransaction> the list of customer cash balance transactions
*/
public static function allCashBalanceTransactions($id, $params = null, $opts = null)
{
return self::_allNestedResources($id, static::PATH_CASH_BALANCE_TRANSACTIONS, $params, $opts);
}
/**
* @param string $id the ID of the customer to which the customer cash balance transaction belongs
* @param string $cashBalanceTransactionId the ID of the customer cash balance transaction to retrieve
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\CustomerCashBalanceTransaction
*/
public static function retrieveCashBalanceTransaction($id, $cashBalanceTransactionId, $params = null, $opts = null)
{
return self::_retrieveNestedResource($id, static::PATH_CASH_BALANCE_TRANSACTIONS, $cashBalanceTransactionId, $params, $opts);
}
const PATH_SOURCES = '/sources';
/**
@ -148,7 +266,7 @@ class Customer extends ApiResource
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Collection the list of payment sources (AlipayAccount, BankAccount, BitcoinReceiver, Card or Source)
* @return \Stripe\Collection<\Stripe\BankAccount|\Stripe\Card|\Stripe\Source> the list of payment sources (BankAccount, Card or Source)
*/
public static function allSources($id, $params = null, $opts = null)
{
@ -162,7 +280,7 @@ class Customer extends ApiResource
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\AlipayAccount|\Stripe\BankAccount|\Stripe\BitcoinReceiver|\Stripe\Card|\Stripe\Source
* @return \Stripe\BankAccount|\Stripe\Card|\Stripe\Source
*/
public static function createSource($id, $params = null, $opts = null)
{
@ -177,7 +295,7 @@ class Customer extends ApiResource
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\AlipayAccount|\Stripe\BankAccount|\Stripe\BitcoinReceiver|\Stripe\Card|\Stripe\Source
* @return \Stripe\BankAccount|\Stripe\Card|\Stripe\Source
*/
public static function deleteSource($id, $sourceId, $params = null, $opts = null)
{
@ -192,7 +310,7 @@ class Customer extends ApiResource
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\AlipayAccount|\Stripe\BankAccount|\Stripe\BitcoinReceiver|\Stripe\Card|\Stripe\Source
* @return \Stripe\BankAccount|\Stripe\Card|\Stripe\Source
*/
public static function retrieveSource($id, $sourceId, $params = null, $opts = null)
{
@ -207,13 +325,12 @@ class Customer extends ApiResource
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\AlipayAccount|\Stripe\BankAccount|\Stripe\BitcoinReceiver|\Stripe\Card|\Stripe\Source
* @return \Stripe\BankAccount|\Stripe\Card|\Stripe\Source
*/
public static function updateSource($id, $sourceId, $params = null, $opts = null)
{
return self::_updateNestedResource($id, static::PATH_SOURCES, $sourceId, $params, $opts);
}
const PATH_TAX_IDS = '/tax_ids';
/**
@ -223,7 +340,7 @@ class Customer extends ApiResource
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Collection the list of tax ids
* @return \Stripe\Collection<\Stripe\TaxId> the list of tax ids
*/
public static function allTaxIds($id, $params = null, $opts = null)
{

View File

@ -29,7 +29,7 @@ namespace Stripe;
* @property null|string|\Stripe\Invoice $invoice The ID of the invoice (if any) related to the transaction.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property null|\Stripe\StripeObject $metadata Set of <a href="https://stripe.com/docs/api/metadata">key-value pairs</a> that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
* @property string $type Transaction type: <code>adjustment</code>, <code>applied_to_invoice</code>, <code>credit_note</code>, <code>initial</code>, <code>invoice_too_large</code>, <code>invoice_too_small</code>, <code>unspent_receiver_credit</code>, or <code>unapplied_from_invoice</code>. See the <a href="https://stripe.com/docs/billing/customer/balance#types">Customer Balance page</a> to learn more about transaction types.
* @property string $type Transaction type: <code>adjustment</code>, <code>applied_to_invoice</code>, <code>credit_note</code>, <code>initial</code>, <code>invoice_overpaid</code>, <code>invoice_too_large</code>, <code>invoice_too_small</code>, <code>unspent_receiver_credit</code>, or <code>unapplied_from_invoice</code>. See the <a href="https://stripe.com/docs/billing/customer/balance#types">Customer Balance page</a> to learn more about transaction types.
*/
class CustomerBalanceTransaction extends ApiResource
{
@ -39,6 +39,7 @@ class CustomerBalanceTransaction extends ApiResource
const TYPE_APPLIED_TO_INVOICE = 'applied_to_invoice';
const TYPE_CREDIT_NOTE = 'credit_note';
const TYPE_INITIAL = 'initial';
const TYPE_INVOICE_OVERPAID = 'invoice_overpaid';
const TYPE_INVOICE_TOO_LARGE = 'invoice_too_large';
const TYPE_INVOICE_TOO_SMALL = 'invoice_too_small';
const TYPE_UNSPENT_RECEIVER_CREDIT = 'unspent_receiver_credit';

View File

@ -0,0 +1,42 @@
<?php
// File generated from our OpenAPI spec
namespace Stripe;
/**
* Customers with certain payments enabled have a cash balance, representing funds
* that were paid by the customer to a merchant, but have not yet been allocated to
* a payment. Cash Balance Transactions represent when funds are moved into or out
* of this balance. This includes funding by the customer, allocation to payments,
* and refunds to the customer.
*
* @property string $id Unique identifier for the object.
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property \Stripe\StripeObject $applied_to_payment
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property string $currency Three-letter <a href="https://www.iso.org/iso-4217-currency-codes.html">ISO currency code</a>, in lowercase. Must be a <a href="https://stripe.com/docs/currencies">supported currency</a>.
* @property string|\Stripe\Customer $customer The customer whose available cash balance changed as a result of this transaction.
* @property int $ending_balance The total available cash balance for the specified currency after this transaction was applied. Represented in the <a href="https://stripe.com/docs/currencies#zero-decimal">smallest currency unit</a>.
* @property \Stripe\StripeObject $funded
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property int $net_amount The amount by which the cash balance changed, represented in the <a href="https://stripe.com/docs/currencies#zero-decimal">smallest currency unit</a>. A positive value represents funds being added to the cash balance, a negative value represents funds being removed from the cash balance.
* @property \Stripe\StripeObject $refunded_from_payment
* @property string $type The type of the cash balance transaction. One of <code>applied_to_payment</code>, <code>unapplied_from_payment</code>, <code>refunded_from_payment</code>, <code>funded</code>, <code>return_initiated</code>, or <code>return_canceled</code>. New types may be added in future. See <a href="https://stripe.com/docs/payments/customer-balance#types">Customer Balance</a> to learn more about these types.
* @property \Stripe\StripeObject $unapplied_from_payment
*/
class CustomerCashBalanceTransaction extends ApiResource
{
const OBJECT_NAME = 'customer_cash_balance_transaction';
use ApiOperations\All;
use ApiOperations\Retrieve;
const TYPE_APPLIED_TO_PAYMENT = 'applied_to_payment';
const TYPE_FUNDED = 'funded';
const TYPE_FUNDING_REVERSED = 'funding_reversed';
const TYPE_REFUNDED_FROM_PAYMENT = 'refunded_from_payment';
const TYPE_RETURN_CANCELED = 'return_canceled';
const TYPE_RETURN_INITIATED = 'return_initiated';
const TYPE_UNAPPLIED_FROM_PAYMENT = 'unapplied_from_payment';
}

View File

@ -0,0 +1,23 @@
<?php
namespace Stripe;
/**
* Class Discount.
*
* @property null|string $checkout_session The Checkout session that this coupon is applied to, if it is applied to a particular session in payment mode. Will not be present for subscription mode.
* @property \Stripe\Coupon $coupon Hash describing the coupon applied to create this discount.
* @property string|\Stripe\Customer $customer The ID of the customer associated with this discount.
* @property null|int $end If the coupon has a duration of repeating, the date that this discount will end. If the coupon has a duration of once or forever, this attribute will be null.
* @property string $id The ID of the discount object.
* @property null|string $invoice The invoice that the discounts coupon was applied to, if it was applied directly to a particular invoice.
* @property null|string $invoice_item The invoice item id (or invoice line item id for invoice line items of type=subscription) that the discounts coupon was applied to, if it was applied directly to a particular invoice item or invoice line item.
* @property string $object String representing the objects type. Objects of the same type share the same value.
* @property null|string $promotion_code The promotion code applied to create this discount.
* @property int $start Date that the coupon was applied.
* @property null|string $subscription The subscription that this coupon is applied to, if it is applied to a particular subscription.
*/
class Discount extends StripeObject
{
const OBJECT_NAME = 'discount';
}

View File

@ -64,17 +64,17 @@ class Dispute extends ApiResource
const STATUS_WON = 'won';
/**
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Dispute the closed dispute
*/
// TODO: add $params to standardize signature
public function close($opts = null)
public function close($params = null, $opts = null)
{
$url = $this->instanceUrl() . '/close';
list($response, $opts) = $this->_request('post', $url, null, $opts);
list($response, $opts) = $this->_request('post', $url, $params, $opts);
$this->refreshFrom($response, $opts);
return $this;

View File

@ -11,7 +11,6 @@ namespace Stripe;
* @property int $expires Time at which the key will expire. Measured in seconds since the Unix epoch.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property string $secret The key's secret. You can use this value to make authorized requests to the Stripe API.
* @property array $associated_objects
*/
class EphemeralKey extends ApiResource
{

View File

@ -26,14 +26,14 @@ namespace Stripe;
* @property string $payment_method_type If the error is specific to the type
* of payment method, the payment method type that had a problem. This
* field is only populated for invoice-related errors.
* @property string $request_log_url A URL to the request log entry in your
* dashboard.
* @property SetupIntent $setup_intent The SetupIntent object for errors
* returned on a request involving a SetupIntent.
* @property StripeObject $source The source object for errors returned on a
* request involving a source.
* @property string $type The type of error returned. One of
* `api_connection_error`, `api_error`, `authentication_error`,
* `card_error`, `idempotency_error`, `invalid_request_error`, or
* `rate_limit_error`.
* @property string $type The type of error returned. One of `api_error`,
* `card_error`, `idempotency_error`, or `invalid_request_error`.
*/
class ErrorObject extends StripeObject
{
@ -42,28 +42,42 @@ class ErrorObject extends StripeObject
*
* @see https://stripe.com/docs/error-codes
*/
const CODE_ACCOUNT_ALREADY_EXISTS = 'account_already_exists';
const CODE_ACCOUNT_COUNTRY_INVALID_ADDRESS = 'account_country_invalid_address';
const CODE_ACCOUNT_ERROR_COUNTRY_CHANGE_REQUIRES_ADDITIONAL_STEPS = 'account_error_country_change_requires_additional_steps';
const CODE_ACCOUNT_INFORMATION_MISMATCH = 'account_information_mismatch';
const CODE_ACCOUNT_INVALID = 'account_invalid';
const CODE_ACCOUNT_NUMBER_INVALID = 'account_number_invalid';
const CODE_ACSS_DEBIT_SESSION_INCOMPLETE = 'acss_debit_session_incomplete';
const CODE_ALIPAY_UPGRADE_REQUIRED = 'alipay_upgrade_required';
const CODE_AMOUNT_TOO_LARGE = 'amount_too_large';
const CODE_AMOUNT_TOO_SMALL = 'amount_too_small';
const CODE_API_KEY_EXPIRED = 'api_key_expired';
const CODE_AUTHENTICATION_REQUIRED = 'authentication_required';
const CODE_BALANCE_INSUFFICIENT = 'balance_insufficient';
const CODE_BANK_ACCOUNT_BAD_ROUTING_NUMBERS = 'bank_account_bad_routing_numbers';
const CODE_BANK_ACCOUNT_DECLINED = 'bank_account_declined';
const CODE_BANK_ACCOUNT_EXISTS = 'bank_account_exists';
const CODE_BANK_ACCOUNT_UNUSABLE = 'bank_account_unusable';
const CODE_BANK_ACCOUNT_UNVERIFIED = 'bank_account_unverified';
const CODE_BANK_ACCOUNT_VERIFICATION_FAILED = 'bank_account_verification_failed';
const CODE_BILLING_INVALID_MANDATE = 'billing_invalid_mandate';
const CODE_BITCOIN_UPGRADE_REQUIRED = 'bitcoin_upgrade_required';
const CODE_CARD_DECLINE_RATE_LIMIT_EXCEEDED = 'card_decline_rate_limit_exceeded';
const CODE_CARD_DECLINED = 'card_declined';
const CODE_CARDHOLDER_PHONE_NUMBER_REQUIRED = 'cardholder_phone_number_required';
const CODE_CHARGE_ALREADY_CAPTURED = 'charge_already_captured';
const CODE_CHARGE_ALREADY_REFUNDED = 'charge_already_refunded';
const CODE_CHARGE_DISPUTED = 'charge_disputed';
const CODE_CHARGE_EXCEEDS_SOURCE_LIMIT = 'charge_exceeds_source_limit';
const CODE_CHARGE_EXPIRED_FOR_CAPTURE = 'charge_expired_for_capture';
const CODE_CHARGE_INVALID_PARAMETER = 'charge_invalid_parameter';
const CODE_CLEARING_CODE_UNSUPPORTED = 'clearing_code_unsupported';
const CODE_COUNTRY_CODE_INVALID = 'country_code_invalid';
const CODE_COUNTRY_UNSUPPORTED = 'country_unsupported';
const CODE_COUPON_EXPIRED = 'coupon_expired';
const CODE_CUSTOMER_MAX_PAYMENT_METHODS = 'customer_max_payment_methods';
const CODE_CUSTOMER_MAX_SUBSCRIPTIONS = 'customer_max_subscriptions';
const CODE_DEBIT_NOT_AUTHORIZED = 'debit_not_authorized';
const CODE_EMAIL_INVALID = 'email_invalid';
const CODE_EXPIRED_CARD = 'expired_card';
const CODE_IDEMPOTENCY_KEY_IN_USE = 'idempotency_key_in_use';
@ -71,8 +85,13 @@ class ErrorObject extends StripeObject
const CODE_INCORRECT_CVC = 'incorrect_cvc';
const CODE_INCORRECT_NUMBER = 'incorrect_number';
const CODE_INCORRECT_ZIP = 'incorrect_zip';
const CODE_INSTANT_PAYOUTS_LIMIT_EXCEEDED = 'instant_payouts_limit_exceeded';
const CODE_INSTANT_PAYOUTS_UNSUPPORTED = 'instant_payouts_unsupported';
const CODE_INSUFFICIENT_FUNDS = 'insufficient_funds';
const CODE_INTENT_INVALID_STATE = 'intent_invalid_state';
const CODE_INTENT_VERIFICATION_METHOD_MISSING = 'intent_verification_method_missing';
const CODE_INVALID_CARD_TYPE = 'invalid_card_type';
const CODE_INVALID_CHARACTERS = 'invalid_characters';
const CODE_INVALID_CHARGE_AMOUNT = 'invalid_charge_amount';
const CODE_INVALID_CVC = 'invalid_cvc';
const CODE_INVALID_EXPIRY_MONTH = 'invalid_expiry_month';
@ -80,18 +99,17 @@ class ErrorObject extends StripeObject
const CODE_INVALID_NUMBER = 'invalid_number';
const CODE_INVALID_SOURCE_USAGE = 'invalid_source_usage';
const CODE_INVOICE_NO_CUSTOMER_LINE_ITEMS = 'invoice_no_customer_line_items';
const CODE_INVOICE_NO_PAYMENT_METHOD_TYPES = 'invoice_no_payment_method_types';
const CODE_INVOICE_NO_SUBSCRIPTION_LINE_ITEMS = 'invoice_no_subscription_line_items';
const CODE_INVOICE_NOT_EDITABLE = 'invoice_not_editable';
const CODE_INVOICE_ON_BEHALF_OF_NOT_EDITABLE = 'invoice_on_behalf_of_not_editable';
const CODE_INVOICE_PAYMENT_INTENT_REQUIRES_ACTION = 'invoice_payment_intent_requires_action';
const CODE_INVOICE_UPCOMING_NONE = 'invoice_upcoming_none';
const CODE_LIVEMODE_MISMATCH = 'livemode_mismatch';
const CODE_LOCK_TIMEOUT = 'lock_timeout';
const CODE_MISSING = 'missing';
const CODE_NO_ACCOUNT = 'no_account';
const CODE_NOT_ALLOWED_ON_STANDARD_ACCOUNT = 'not_allowed_on_standard_account';
const CODE_ORDER_CREATION_FAILED = 'order_creation_failed';
const CODE_ORDER_REQUIRED_SETTINGS = 'order_required_settings';
const CODE_ORDER_STATUS_INVALID = 'order_status_invalid';
const CODE_ORDER_UPSTREAM_TIMEOUT = 'order_upstream_timeout';
const CODE_OUT_OF_INVENTORY = 'out_of_inventory';
const CODE_PARAMETER_INVALID_EMPTY = 'parameter_invalid_empty';
const CODE_PARAMETER_INVALID_INTEGER = 'parameter_invalid_integer';
@ -100,38 +118,64 @@ class ErrorObject extends StripeObject
const CODE_PARAMETER_MISSING = 'parameter_missing';
const CODE_PARAMETER_UNKNOWN = 'parameter_unknown';
const CODE_PARAMETERS_EXCLUSIVE = 'parameters_exclusive';
const CODE_PAYMENT_INTENT_ACTION_REQUIRED = 'payment_intent_action_required';
const CODE_PAYMENT_INTENT_AUTHENTICATION_FAILURE = 'payment_intent_authentication_failure';
const CODE_PAYMENT_INTENT_INCOMPATIBLE_PAYMENT_METHOD = 'payment_intent_incompatible_payment_method';
const CODE_PAYMENT_INTENT_INVALID_PARAMETER = 'payment_intent_invalid_parameter';
const CODE_PAYMENT_INTENT_KONBINI_REJECTED_CONFIRMATION_NUMBER = 'payment_intent_konbini_rejected_confirmation_number';
const CODE_PAYMENT_INTENT_MANDATE_INVALID = 'payment_intent_mandate_invalid';
const CODE_PAYMENT_INTENT_PAYMENT_ATTEMPT_EXPIRED = 'payment_intent_payment_attempt_expired';
const CODE_PAYMENT_INTENT_PAYMENT_ATTEMPT_FAILED = 'payment_intent_payment_attempt_failed';
const CODE_PAYMENT_INTENT_UNEXPECTED_STATE = 'payment_intent_unexpected_state';
const CODE_PAYMENT_METHOD_BANK_ACCOUNT_ALREADY_VERIFIED = 'payment_method_bank_account_already_verified';
const CODE_PAYMENT_METHOD_BANK_ACCOUNT_BLOCKED = 'payment_method_bank_account_blocked';
const CODE_PAYMENT_METHOD_BILLING_DETAILS_ADDRESS_MISSING = 'payment_method_billing_details_address_missing';
const CODE_PAYMENT_METHOD_CURRENCY_MISMATCH = 'payment_method_currency_mismatch';
const CODE_PAYMENT_METHOD_INVALID_PARAMETER = 'payment_method_invalid_parameter';
const CODE_PAYMENT_METHOD_INVALID_PARAMETER_TESTMODE = 'payment_method_invalid_parameter_testmode';
const CODE_PAYMENT_METHOD_MICRODEPOSIT_FAILED = 'payment_method_microdeposit_failed';
const CODE_PAYMENT_METHOD_MICRODEPOSIT_VERIFICATION_AMOUNTS_INVALID = 'payment_method_microdeposit_verification_amounts_invalid';
const CODE_PAYMENT_METHOD_MICRODEPOSIT_VERIFICATION_AMOUNTS_MISMATCH = 'payment_method_microdeposit_verification_amounts_mismatch';
const CODE_PAYMENT_METHOD_MICRODEPOSIT_VERIFICATION_ATTEMPTS_EXCEEDED = 'payment_method_microdeposit_verification_attempts_exceeded';
const CODE_PAYMENT_METHOD_MICRODEPOSIT_VERIFICATION_DESCRIPTOR_CODE_MISMATCH = 'payment_method_microdeposit_verification_descriptor_code_mismatch';
const CODE_PAYMENT_METHOD_MICRODEPOSIT_VERIFICATION_TIMEOUT = 'payment_method_microdeposit_verification_timeout';
const CODE_PAYMENT_METHOD_PROVIDER_DECLINE = 'payment_method_provider_decline';
const CODE_PAYMENT_METHOD_PROVIDER_TIMEOUT = 'payment_method_provider_timeout';
const CODE_PAYMENT_METHOD_UNACTIVATED = 'payment_method_unactivated';
const CODE_PAYMENT_METHOD_UNEXPECTED_STATE = 'payment_method_unexpected_state';
const CODE_PAYMENT_METHOD_UNSUPPORTED_TYPE = 'payment_method_unsupported_type';
const CODE_PAYOUTS_NOT_ALLOWED = 'payouts_not_allowed';
const CODE_PLATFORM_ACCOUNT_REQUIRED = 'platform_account_required';
const CODE_PLATFORM_API_KEY_EXPIRED = 'platform_api_key_expired';
const CODE_POSTAL_CODE_INVALID = 'postal_code_invalid';
const CODE_PROCESSING_ERROR = 'processing_error';
const CODE_PRODUCT_INACTIVE = 'product_inactive';
const CODE_RATE_LIMIT = 'rate_limit';
const CODE_REFER_TO_CUSTOMER = 'refer_to_customer';
const CODE_REFUND_DISPUTED_PAYMENT = 'refund_disputed_payment';
const CODE_RESOURCE_ALREADY_EXISTS = 'resource_already_exists';
const CODE_RESOURCE_MISSING = 'resource_missing';
const CODE_RETURN_INTENT_ALREADY_PROCESSED = 'return_intent_already_processed';
const CODE_ROUTING_NUMBER_INVALID = 'routing_number_invalid';
const CODE_SECRET_KEY_REQUIRED = 'secret_key_required';
const CODE_SEPA_UNSUPPORTED_ACCOUNT = 'sepa_unsupported_account';
const CODE_SETUP_ATTEMPT_FAILED = 'setup_attempt_failed';
const CODE_SETUP_INTENT_AUTHENTICATION_FAILURE = 'setup_intent_authentication_failure';
const CODE_SETUP_INTENT_INVALID_PARAMETER = 'setup_intent_invalid_parameter';
const CODE_SETUP_INTENT_SETUP_ATTEMPT_EXPIRED = 'setup_intent_setup_attempt_expired';
const CODE_SETUP_INTENT_UNEXPECTED_STATE = 'setup_intent_unexpected_state';
const CODE_SHIPPING_CALCULATION_FAILED = 'shipping_calculation_failed';
const CODE_SKU_INACTIVE = 'sku_inactive';
const CODE_STATE_UNSUPPORTED = 'state_unsupported';
const CODE_TAX_ID_INVALID = 'tax_id_invalid';
const CODE_TAXES_CALCULATION_FAILED = 'taxes_calculation_failed';
const CODE_TERMINAL_LOCATION_COUNTRY_UNSUPPORTED = 'terminal_location_country_unsupported';
const CODE_TESTMODE_CHARGES_ONLY = 'testmode_charges_only';
const CODE_TLS_VERSION_UNSUPPORTED = 'tls_version_unsupported';
const CODE_TOKEN_ALREADY_USED = 'token_already_used';
const CODE_TOKEN_IN_USE = 'token_in_use';
const CODE_TRANSFER_SOURCE_BALANCE_PARAMETERS_MISMATCH = 'transfer_source_balance_parameters_mismatch';
const CODE_TRANSFERS_NOT_ALLOWED = 'transfers_not_allowed';
const CODE_UPSTREAM_ORDER_CREATION_FAILED = 'upstream_order_creation_failed';
const CODE_URL_INVALID = 'url_invalid';
/**

View File

@ -39,6 +39,9 @@ namespace Stripe;
* href="https://stripe.com/docs/api#retrieve_event">Retrieve Event API</a> is
* guaranteed only for 30 days.
*
* This class includes constants for the possible string representations of
* event types. See https://stripe.com/docs/api#event_types for more details.
*
* @property string $id Unique identifier for the object.
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property string $account The connected account that originated the event.
@ -57,38 +60,38 @@ class Event extends ApiResource
use ApiOperations\All;
use ApiOperations\Retrieve;
/**
* Possible string representations of event types.
*
* @see https://stripe.com/docs/api#event_types
*/
const ACCOUNT_UPDATED = 'account.updated';
const ACCOUNT_APPLICATION_AUTHORIZED = 'account.application.authorized';
const ACCOUNT_APPLICATION_DEAUTHORIZED = 'account.application.deauthorized';
const ACCOUNT_EXTERNAL_ACCOUNT_CREATED = 'account.external_account.created';
const ACCOUNT_EXTERNAL_ACCOUNT_DELETED = 'account.external_account.deleted';
const ACCOUNT_EXTERNAL_ACCOUNT_UPDATED = 'account.external_account.updated';
const ACCOUNT_UPDATED = 'account.updated';
const APPLICATION_FEE_CREATED = 'application_fee.created';
const APPLICATION_FEE_REFUNDED = 'application_fee.refunded';
const APPLICATION_FEE_REFUND_UPDATED = 'application_fee.refund.updated';
const APPLICATION_FEE_REFUNDED = 'application_fee.refunded';
const BALANCE_AVAILABLE = 'balance.available';
const BILLING_PORTAL_CONFIGURATION_CREATED = 'billing_portal.configuration.created';
const BILLING_PORTAL_CONFIGURATION_UPDATED = 'billing_portal.configuration.updated';
const BILLING_PORTAL_SESSION_CREATED = 'billing_portal.session.created';
const CAPABILITY_UPDATED = 'capability.updated';
const CASH_BALANCE_FUNDS_AVAILABLE = 'cash_balance.funds_available';
const CHARGE_CAPTURED = 'charge.captured';
const CHARGE_EXPIRED = 'charge.expired';
const CHARGE_FAILED = 'charge.failed';
const CHARGE_PENDING = 'charge.pending';
const CHARGE_REFUNDED = 'charge.refunded';
const CHARGE_SUCCEEDED = 'charge.succeeded';
const CHARGE_UPDATED = 'charge.updated';
const CHARGE_DISPUTE_CLOSED = 'charge.dispute.closed';
const CHARGE_DISPUTE_CREATED = 'charge.dispute.created';
const CHARGE_DISPUTE_FUNDS_REINSTATED = 'charge.dispute.funds_reinstated';
const CHARGE_DISPUTE_FUNDS_WITHDRAWN = 'charge.dispute.funds_withdrawn';
const CHARGE_DISPUTE_UPDATED = 'charge.dispute.updated';
const CHARGE_EXPIRED = 'charge.expired';
const CHARGE_FAILED = 'charge.failed';
const CHARGE_PENDING = 'charge.pending';
const CHARGE_REFUND_UPDATED = 'charge.refund.updated';
const CHARGE_REFUNDED = 'charge.refunded';
const CHARGE_SUCCEEDED = 'charge.succeeded';
const CHARGE_UPDATED = 'charge.updated';
const CHECKOUT_SESSION_ASYNC_PAYMENT_FAILED = 'checkout.session.async_payment_failed';
const CHECKOUT_SESSION_ASYNC_PAYMENT_SUCCEEDED = 'checkout.session.async_payment_succeeded';
const CHECKOUT_SESSION_COMPLETED = 'checkout.session.completed';
const CHECKOUT_SESSION_EXPIRED = 'checkout.session.expired';
const COUPON_CREATED = 'coupon.created';
const COUPON_DELETED = 'coupon.deleted';
const COUPON_UPDATED = 'coupon.updated';
@ -97,7 +100,6 @@ class Event extends ApiResource
const CREDIT_NOTE_VOIDED = 'credit_note.voided';
const CUSTOMER_CREATED = 'customer.created';
const CUSTOMER_DELETED = 'customer.deleted';
const CUSTOMER_UPDATED = 'customer.updated';
const CUSTOMER_DISCOUNT_CREATED = 'customer.discount.created';
const CUSTOMER_DISCOUNT_DELETED = 'customer.discount.deleted';
const CUSTOMER_DISCOUNT_UPDATED = 'customer.discount.updated';
@ -107,14 +109,29 @@ class Event extends ApiResource
const CUSTOMER_SOURCE_UPDATED = 'customer.source.updated';
const CUSTOMER_SUBSCRIPTION_CREATED = 'customer.subscription.created';
const CUSTOMER_SUBSCRIPTION_DELETED = 'customer.subscription.deleted';
const CUSTOMER_SUBSCRIPTION_PAUSED = 'customer.subscription.paused';
const CUSTOMER_SUBSCRIPTION_PENDING_UPDATE_APPLIED = 'customer.subscription.pending_update_applied';
const CUSTOMER_SUBSCRIPTION_PENDING_UPDATE_EXPIRED = 'customer.subscription.pending_update_expired';
const CUSTOMER_SUBSCRIPTION_RESUMED = 'customer.subscription.resumed';
const CUSTOMER_SUBSCRIPTION_TRIAL_WILL_END = 'customer.subscription.trial_will_end';
const CUSTOMER_SUBSCRIPTION_UPDATED = 'customer.subscription.updated';
const CUSTOMER_TAX_ID_CREATED = 'customer.tax_id.created';
const CUSTOMER_TAX_ID_DELETED = 'customer.tax_id.deleted';
const CUSTOMER_TAX_ID_UPDATED = 'customer.tax_id.updated';
const CUSTOMER_UPDATED = 'customer.updated';
const CUSTOMER_CASH_BALANCE_TRANSACTION_CREATED = 'customer_cash_balance_transaction.created';
const FILE_CREATED = 'file.created';
const FINANCIAL_CONNECTIONS_ACCOUNT_CREATED = 'financial_connections.account.created';
const FINANCIAL_CONNECTIONS_ACCOUNT_DEACTIVATED = 'financial_connections.account.deactivated';
const FINANCIAL_CONNECTIONS_ACCOUNT_DISCONNECTED = 'financial_connections.account.disconnected';
const FINANCIAL_CONNECTIONS_ACCOUNT_REACTIVATED = 'financial_connections.account.reactivated';
const FINANCIAL_CONNECTIONS_ACCOUNT_REFRESHED_BALANCE = 'financial_connections.account.refreshed_balance';
const IDENTITY_VERIFICATION_SESSION_CANCELED = 'identity.verification_session.canceled';
const IDENTITY_VERIFICATION_SESSION_CREATED = 'identity.verification_session.created';
const IDENTITY_VERIFICATION_SESSION_PROCESSING = 'identity.verification_session.processing';
const IDENTITY_VERIFICATION_SESSION_REDACTED = 'identity.verification_session.redacted';
const IDENTITY_VERIFICATION_SESSION_REQUIRES_INPUT = 'identity.verification_session.requires_input';
const IDENTITY_VERIFICATION_SESSION_VERIFIED = 'identity.verification_session.verified';
const INVOICE_CREATED = 'invoice.created';
const INVOICE_DELETED = 'invoice.deleted';
const INVOICE_FINALIZATION_FAILED = 'invoice.finalization_failed';
@ -131,7 +148,6 @@ class Event extends ApiResource
const INVOICEITEM_CREATED = 'invoiceitem.created';
const INVOICEITEM_DELETED = 'invoiceitem.deleted';
const INVOICEITEM_UPDATED = 'invoiceitem.updated';
const ISSUER_FRAUD_RECORD_CREATED = 'issuer_fraud_record.created';
const ISSUING_AUTHORIZATION_CREATED = 'issuing_authorization.created';
const ISSUING_AUTHORIZATION_REQUEST = 'issuing_authorization.request';
const ISSUING_AUTHORIZATION_UPDATED = 'issuing_authorization.updated';
@ -148,20 +164,18 @@ class Event extends ApiResource
const ISSUING_TRANSACTION_UPDATED = 'issuing_transaction.updated';
const MANDATE_UPDATED = 'mandate.updated';
const ORDER_CREATED = 'order.created';
const ORDER_PAYMENT_FAILED = 'order.payment_failed';
const ORDER_PAYMENT_SUCCEEDED = 'order.payment_succeeded';
const ORDER_UPDATED = 'order.updated';
const ORDER_RETURN_CREATED = 'order_return.created';
const PAYMENT_INTENT_AMOUNT_CAPTURABLE_UPDATED = 'payment_intent.amount_capturable_updated';
const PAYMENT_INTENT_CANCELED = 'payment_intent.canceled';
const PAYMENT_INTENT_CREATED = 'payment_intent.created';
const PAYMENT_INTENT_PARTIALLY_FUNDED = 'payment_intent.partially_funded';
const PAYMENT_INTENT_PAYMENT_FAILED = 'payment_intent.payment_failed';
const PAYMENT_INTENT_PROCESSING = 'payment_intent.processing';
const PAYMENT_INTENT_REQUIRES_ACTION = 'payment_intent.requires_action';
const PAYMENT_INTENT_SUCCEEDED = 'payment_intent.succeeded';
const PAYMENT_LINK_CREATED = 'payment_link.created';
const PAYMENT_LINK_UPDATED = 'payment_link.updated';
const PAYMENT_METHOD_ATTACHED = 'payment_method.attached';
const PAYMENT_METHOD_AUTOMATICALLY_UPDATED = 'payment_method.automatically_updated';
const PAYMENT_METHOD_CARD_AUTOMATICALLY_UPDATED = 'payment_method.card_automatically_updated';
const PAYMENT_METHOD_DETACHED = 'payment_method.detached';
const PAYMENT_METHOD_UPDATED = 'payment_method.updated';
const PAYOUT_CANCELED = 'payout.canceled';
@ -172,7 +186,6 @@ class Event extends ApiResource
const PERSON_CREATED = 'person.created';
const PERSON_DELETED = 'person.deleted';
const PERSON_UPDATED = 'person.updated';
const PING = 'ping';
const PLAN_CREATED = 'plan.created';
const PLAN_DELETED = 'plan.deleted';
const PLAN_UPDATED = 'plan.updated';
@ -183,13 +196,18 @@ class Event extends ApiResource
const PRODUCT_DELETED = 'product.deleted';
const PRODUCT_UPDATED = 'product.updated';
const PROMOTION_CODE_CREATED = 'promotion_code.created';
const PROMOTION_CODE_DELETED = 'promotion_code.deleted';
const PROMOTION_CODE_UPDATED = 'promotion_code.updated';
const QUOTE_ACCEPTED = 'quote.accepted';
const QUOTE_CANCELED = 'quote.canceled';
const QUOTE_CREATED = 'quote.created';
const QUOTE_FINALIZED = 'quote.finalized';
const RADAR_EARLY_FRAUD_WARNING_CREATED = 'radar.early_fraud_warning.created';
const RADAR_EARLY_FRAUD_WARNING_UPDATED = 'radar.early_fraud_warning.updated';
const RECIPIENT_CREATED = 'recipient.created';
const RECIPIENT_DELETED = 'recipient.deleted';
const RECIPIENT_UPDATED = 'recipient.updated';
const REFUND_CREATED = 'refund.created';
const REFUND_UPDATED = 'refund.updated';
const REPORTING_REPORT_RUN_FAILED = 'reporting.report_run.failed';
const REPORTING_REPORT_RUN_SUCCEEDED = 'reporting.report_run.succeeded';
const REPORTING_REPORT_TYPE_UPDATED = 'reporting.report_type.updated';
@ -220,6 +238,13 @@ class Event extends ApiResource
const SUBSCRIPTION_SCHEDULE_UPDATED = 'subscription_schedule.updated';
const TAX_RATE_CREATED = 'tax_rate.created';
const TAX_RATE_UPDATED = 'tax_rate.updated';
const TERMINAL_READER_ACTION_FAILED = 'terminal.reader.action_failed';
const TERMINAL_READER_ACTION_SUCCEEDED = 'terminal.reader.action_succeeded';
const TEST_HELPERS_TEST_CLOCK_ADVANCING = 'test_helpers.test_clock.advancing';
const TEST_HELPERS_TEST_CLOCK_CREATED = 'test_helpers.test_clock.created';
const TEST_HELPERS_TEST_CLOCK_DELETED = 'test_helpers.test_clock.deleted';
const TEST_HELPERS_TEST_CLOCK_INTERNAL_FAILURE = 'test_helpers.test_clock.internal_failure';
const TEST_HELPERS_TEST_CLOCK_READY = 'test_helpers.test_clock.ready';
const TOPUP_CANCELED = 'topup.canceled';
const TOPUP_CREATED = 'topup.created';
const TOPUP_FAILED = 'topup.failed';
@ -228,4 +253,32 @@ class Event extends ApiResource
const TRANSFER_CREATED = 'transfer.created';
const TRANSFER_REVERSED = 'transfer.reversed';
const TRANSFER_UPDATED = 'transfer.updated';
const TREASURY_CREDIT_REVERSAL_CREATED = 'treasury.credit_reversal.created';
const TREASURY_CREDIT_REVERSAL_POSTED = 'treasury.credit_reversal.posted';
const TREASURY_DEBIT_REVERSAL_COMPLETED = 'treasury.debit_reversal.completed';
const TREASURY_DEBIT_REVERSAL_CREATED = 'treasury.debit_reversal.created';
const TREASURY_DEBIT_REVERSAL_INITIAL_CREDIT_GRANTED = 'treasury.debit_reversal.initial_credit_granted';
const TREASURY_FINANCIAL_ACCOUNT_CLOSED = 'treasury.financial_account.closed';
const TREASURY_FINANCIAL_ACCOUNT_CREATED = 'treasury.financial_account.created';
const TREASURY_FINANCIAL_ACCOUNT_FEATURES_STATUS_UPDATED = 'treasury.financial_account.features_status_updated';
const TREASURY_INBOUND_TRANSFER_CANCELED = 'treasury.inbound_transfer.canceled';
const TREASURY_INBOUND_TRANSFER_CREATED = 'treasury.inbound_transfer.created';
const TREASURY_INBOUND_TRANSFER_FAILED = 'treasury.inbound_transfer.failed';
const TREASURY_INBOUND_TRANSFER_SUCCEEDED = 'treasury.inbound_transfer.succeeded';
const TREASURY_OUTBOUND_PAYMENT_CANCELED = 'treasury.outbound_payment.canceled';
const TREASURY_OUTBOUND_PAYMENT_CREATED = 'treasury.outbound_payment.created';
const TREASURY_OUTBOUND_PAYMENT_EXPECTED_ARRIVAL_DATE_UPDATED = 'treasury.outbound_payment.expected_arrival_date_updated';
const TREASURY_OUTBOUND_PAYMENT_FAILED = 'treasury.outbound_payment.failed';
const TREASURY_OUTBOUND_PAYMENT_POSTED = 'treasury.outbound_payment.posted';
const TREASURY_OUTBOUND_PAYMENT_RETURNED = 'treasury.outbound_payment.returned';
const TREASURY_OUTBOUND_TRANSFER_CANCELED = 'treasury.outbound_transfer.canceled';
const TREASURY_OUTBOUND_TRANSFER_CREATED = 'treasury.outbound_transfer.created';
const TREASURY_OUTBOUND_TRANSFER_EXPECTED_ARRIVAL_DATE_UPDATED = 'treasury.outbound_transfer.expected_arrival_date_updated';
const TREASURY_OUTBOUND_TRANSFER_FAILED = 'treasury.outbound_transfer.failed';
const TREASURY_OUTBOUND_TRANSFER_POSTED = 'treasury.outbound_transfer.posted';
const TREASURY_OUTBOUND_TRANSFER_RETURNED = 'treasury.outbound_transfer.returned';
const TREASURY_RECEIVED_CREDIT_CREATED = 'treasury.received_credit.created';
const TREASURY_RECEIVED_CREDIT_FAILED = 'treasury.received_credit.failed';
const TREASURY_RECEIVED_CREDIT_SUCCEEDED = 'treasury.received_credit.succeeded';
const TREASURY_RECEIVED_DEBIT_CREATED = 'treasury.received_debit.created';
}

View File

@ -20,7 +20,7 @@ namespace Stripe;
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property null|int $expires_at The time at which the file expires and is no longer available in epoch seconds.
* @property null|string $filename A filename for the file, suitable for saving to a filesystem.
* @property null|\Stripe\Collection $links A list of <a href="https://stripe.com/docs/api#file_links">file links</a> that point at this file.
* @property null|\Stripe\Collection<\Stripe\FileLink> $links A list of <a href="https://stripe.com/docs/api#file_links">file links</a> that point at this file.
* @property string $purpose The <a href="https://stripe.com/docs/file-upload#uploading-a-file">purpose</a> of the uploaded file.
* @property int $size The size in bytes of the file object.
* @property null|string $title A user friendly title for the document.
@ -40,9 +40,15 @@ class File extends ApiResource
const PURPOSE_BUSINESS_LOGO = 'business_logo';
const PURPOSE_CUSTOMER_SIGNATURE = 'customer_signature';
const PURPOSE_DISPUTE_EVIDENCE = 'dispute_evidence';
const PURPOSE_DOCUMENT_PROVIDER_IDENTITY_DOCUMENT = 'document_provider_identity_document';
const PURPOSE_FINANCE_REPORT_RUN = 'finance_report_run';
const PURPOSE_IDENTITY_DOCUMENT = 'identity_document';
const PURPOSE_IDENTITY_DOCUMENT_DOWNLOADABLE = 'identity_document_downloadable';
const PURPOSE_PCI_DOCUMENT = 'pci_document';
const PURPOSE_SELFIE = 'selfie';
const PURPOSE_SIGMA_SCHEDULED_QUERY = 'sigma_scheduled_query';
const PURPOSE_TAX_DOCUMENT_USER_UPLOAD = 'tax_document_user_upload';
const PURPOSE_TERMINAL_READER_SPLASHSCREEN = 'terminal_reader_splashscreen';
// This resource can have two different object names. In latter API
// versions, only `file` is used, but since stripe-php may be used with
@ -54,11 +60,6 @@ class File extends ApiResource
create as protected _create;
}
public static function classUrl()
{
return '/v1/files';
}
/**
* @param null|array $params
* @param null|array|string $opts

View File

@ -0,0 +1,104 @@
<?php
// File generated from our OpenAPI spec
namespace Stripe\FinancialConnections;
/**
* A Financial Connections Account represents an account that exists outside of
* Stripe, to which you have been granted some degree of access.
*
* @property string $id Unique identifier for the object.
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property null|\Stripe\StripeObject $account_holder The account holder that this account belongs to.
* @property null|\Stripe\StripeObject $balance The most recent information about the account's balance.
* @property null|\Stripe\StripeObject $balance_refresh The state of the most recent attempt to refresh the account balance.
* @property string $category The type of the account. Account category is further divided in <code>subcategory</code>.
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property null|string $display_name A human-readable name that has been assigned to this account, either by the account holder or by the institution.
* @property string $institution_name The name of the institution that holds this account.
* @property null|string $last4 The last 4 digits of the account number. If present, this will be 4 numeric characters.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property null|string|\Stripe\FinancialConnections\AccountOwnership $ownership The most recent information about the account's owners.
* @property null|\Stripe\StripeObject $ownership_refresh The state of the most recent attempt to refresh the account owners.
* @property null|string[] $permissions The list of permissions granted by this account.
* @property string $status The status of the link to the account.
* @property string $subcategory <p>If <code>category</code> is <code>cash</code>, one of:</p><p>- <code>checking</code> - <code>savings</code> - <code>other</code></p><p>If <code>category</code> is <code>credit</code>, one of:</p><p>- <code>mortgage</code> - <code>line_of_credit</code> - <code>credit_card</code> - <code>other</code></p><p>If <code>category</code> is <code>investment</code> or <code>other</code>, this will be <code>other</code>.</p>
* @property string[] $supported_payment_method_types The <a href="https://stripe.com/docs/api/payment_methods/object#payment_method_object-type">PaymentMethod type</a>(s) that can be created from this account.
*/
class Account extends \Stripe\ApiResource
{
const OBJECT_NAME = 'financial_connections.account';
use \Stripe\ApiOperations\All;
use \Stripe\ApiOperations\Retrieve;
const CATEGORY_CASH = 'cash';
const CATEGORY_CREDIT = 'credit';
const CATEGORY_INVESTMENT = 'investment';
const CATEGORY_OTHER = 'other';
const STATUS_ACTIVE = 'active';
const STATUS_DISCONNECTED = 'disconnected';
const STATUS_INACTIVE = 'inactive';
const SUBCATEGORY_CHECKING = 'checking';
const SUBCATEGORY_CREDIT_CARD = 'credit_card';
const SUBCATEGORY_LINE_OF_CREDIT = 'line_of_credit';
const SUBCATEGORY_MORTGAGE = 'mortgage';
const SUBCATEGORY_OTHER = 'other';
const SUBCATEGORY_SAVINGS = 'savings';
/**
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\FinancialConnections\Account the disconnected account
*/
public function disconnect($params = null, $opts = null)
{
$url = $this->instanceUrl() . '/disconnect';
list($response, $opts) = $this->_request('post', $url, $params, $opts);
$this->refreshFrom($response, $opts);
return $this;
}
/**
* @param string $id
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Collection<\Stripe\FinancialConnections\AccountOwner> list of BankConnectionsResourceOwners
*/
public static function allOwners($id, $params = null, $opts = null)
{
$url = static::resourceUrl($id) . '/owners';
list($response, $opts) = static::_staticRequest('get', $url, $params, $opts);
$obj = \Stripe\Util\Util::convertToStripeObject($response->json, $opts);
$obj->setLastResponse($response);
return $obj;
}
/**
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\FinancialConnections\Account the refreshed account
*/
public function refreshAccount($params = null, $opts = null)
{
$url = $this->instanceUrl() . '/refresh';
list($response, $opts) = $this->_request('post', $url, $params, $opts);
$this->refreshFrom($response, $opts);
return $this;
}
}

View File

@ -0,0 +1,20 @@
<?php
// File generated from our OpenAPI spec
namespace Stripe\FinancialConnections;
/**
* @property string $id Unique identifier for the object.
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property null|string $email The email address of the owner.
* @property string $name The full name of the owner.
* @property string $ownership The ownership object that this owner belongs to.
* @property null|string $phone The raw phone number of the owner.
* @property null|string $raw_address The raw physical address of the owner.
* @property null|int $refreshed_at The timestamp of the refresh that updated this owner.
*/
class AccountOwner extends \Stripe\ApiResource
{
const OBJECT_NAME = 'financial_connections.account_owner';
}

View File

@ -0,0 +1,18 @@
<?php
// File generated from our OpenAPI spec
namespace Stripe\FinancialConnections;
/**
* Describes a snapshot of the owners of an account at a particular point in time.
*
* @property string $id Unique identifier for the object.
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property \Stripe\Collection<\Stripe\FinancialConnections\AccountOwner> $owners A paginated list of owners for this account.
*/
class AccountOwnership extends \Stripe\ApiResource
{
const OBJECT_NAME = 'financial_connections.account_ownership';
}

View File

@ -0,0 +1,27 @@
<?php
// File generated from our OpenAPI spec
namespace Stripe\FinancialConnections;
/**
* A Financial Connections Session is the secure way to programmatically launch the
* client-side Stripe.js modal that lets your users link their accounts.
*
* @property string $id Unique identifier for the object.
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property null|\Stripe\StripeObject $account_holder The account holder for whom accounts are collected in this session.
* @property \Stripe\Collection<\Stripe\FinancialConnections\Account> $accounts The accounts that were collected as part of this Session.
* @property string $client_secret A value that will be passed to the client to launch the authentication flow.
* @property \Stripe\StripeObject $filters
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property string[] $permissions Permissions requested for accounts collected during this session.
* @property string $return_url For webview integrations only. Upon completing OAuth login in the native browser, the user will be redirected to this URL to return to your app.
*/
class Session extends \Stripe\ApiResource
{
const OBJECT_NAME = 'financial_connections.session';
use \Stripe\ApiOperations\Create;
use \Stripe\ApiOperations\Retrieve;
}

View File

@ -0,0 +1,28 @@
<?php
// File generated from our OpenAPI spec
namespace Stripe;
/**
* Each customer has a <a
* href="https://stripe.com/docs/api/customers/object#customer_object-balance"><code>balance</code></a>
* that is automatically applied to future invoices and payments using the
* <code>customer_balance</code> payment method. Customers can fund this balance by
* initiating a bank transfer to any account in the
* <code>financial_addresses</code> field. Related guide: <a
* href="https://stripe.com/docs/payments/customer-balance/funding-instructions">Customer
* Balance - Funding Instructions</a> to learn more.
*
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property \Stripe\StripeObject $bank_transfer
* @property string $currency Three-letter <a href="https://www.iso.org/iso-4217-currency-codes.html">ISO currency code</a>, in lowercase. Must be a <a href="https://stripe.com/docs/currencies">supported currency</a>.
* @property string $funding_type The <code>funding_type</code> of the returned instructions
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
*/
class FundingInstructions extends ApiResource
{
const OBJECT_NAME = 'funding_instructions';
const FUNDING_TYPE_BANK_TRANSFER = 'bank_transfer';
}

View File

@ -24,17 +24,17 @@ if (!\defined('CURL_HTTP_VERSION_2TLS')) {
\define('CURL_HTTP_VERSION_2TLS', 4);
}
class CurlClient implements ClientInterface
class CurlClient implements ClientInterface, StreamingClientInterface
{
private static $instance;
protected static $instance;
public static function instance()
{
if (!self::$instance) {
self::$instance = new self();
if (!static::$instance) {
static::$instance = new static();
}
return self::$instance;
return static::$instance;
}
protected $defaultOptions;
@ -193,7 +193,7 @@ class CurlClient implements ClientInterface
// END OF USER DEFINED TIMEOUTS
public function request($method, $absUrl, $headers, $params, $hasFile)
private function constructRequest($method, $absUrl, $headers, $params, $hasFile)
{
$method = \strtolower($method);
@ -271,20 +271,215 @@ class CurlClient implements ClientInterface
$opts[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_2TLS;
}
// Stripe's API servers are only accessible over IPv4. Force IPv4 resolving to avoid
// potential issues (cf. https://github.com/stripe/stripe-php/issues/1045).
$opts[\CURLOPT_IPRESOLVE] = \CURL_IPRESOLVE_V4;
// If the user didn't explicitly specify a CURLOPT_IPRESOLVE option, we
// force IPv4 resolving as Stripe's API servers are only accessible over
// IPv4 (see. https://github.com/stripe/stripe-php/issues/1045).
// We let users specify a custom option in case they need to say proxy
// through an IPv6 proxy.
if (!isset($opts[\CURLOPT_IPRESOLVE])) {
$opts[\CURLOPT_IPRESOLVE] = \CURL_IPRESOLVE_V4;
}
return [$opts, $absUrl];
}
public function request($method, $absUrl, $headers, $params, $hasFile)
{
list($opts, $absUrl) = $this->constructRequest($method, $absUrl, $headers, $params, $hasFile);
list($rbody, $rcode, $rheaders) = $this->executeRequestWithRetries($opts, $absUrl);
return [$rbody, $rcode, $rheaders];
}
public function requestStream($method, $absUrl, $headers, $params, $hasFile, $readBodyChunk)
{
list($opts, $absUrl) = $this->constructRequest($method, $absUrl, $headers, $params, $hasFile);
$opts[\CURLOPT_RETURNTRANSFER] = false;
list($rbody, $rcode, $rheaders) = $this->executeStreamingRequestWithRetries($opts, $absUrl, $readBodyChunk);
return [$rbody, $rcode, $rheaders];
}
/**
* Curl permits sending \CURLOPT_HEADERFUNCTION, which is called with lines
* from the header and \CURLOPT_WRITEFUNCTION, which is called with bytes
* from the body. You usually want to handle the body differently depending
* on what was in the header.
*
* This function makes it easier to specify different callbacks depending
* on the contents of the heeder. After the header has been completely read
* and the body begins to stream, it will call $determineWriteCallback with
* the array of headers. $determineWriteCallback should, based on the
* headers it receives, return a "writeCallback" that describes what to do
* with the incoming HTTP response body.
*
* @param array $opts
* @param callable $determineWriteCallback
*
* @return array
*/
private function useHeadersToDetermineWriteCallback($opts, $determineWriteCallback)
{
$rheaders = new Util\CaseInsensitiveArray();
$headerCallback = function ($curl, $header_line) use (&$rheaders) {
return self::parseLineIntoHeaderArray($header_line, $rheaders);
};
$writeCallback = null;
$writeCallbackWrapper = function ($curl, $data) use (&$writeCallback, &$rheaders, &$determineWriteCallback) {
if (null === $writeCallback) {
$writeCallback = \call_user_func_array($determineWriteCallback, [$rheaders]);
}
return \call_user_func_array($writeCallback, [$curl, $data]);
};
return [$headerCallback, $writeCallbackWrapper];
}
private static function parseLineIntoHeaderArray($line, &$headers)
{
if (false === \strpos($line, ':')) {
return \strlen($line);
}
list($key, $value) = \explode(':', \trim($line), 2);
$headers[\trim($key)] = \trim($value);
return \strlen($line);
}
/**
* Like `executeRequestWithRetries` except:
* 1. Does not buffer the body of a successful (status code < 300)
* response into memory -- instead, calls the caller-provided
* $readBodyChunk with each chunk of incoming data.
* 2. Does not retry if a network error occurs while streaming the
* body of a successful response.
*
* @param array $opts cURL options
* @param string $absUrl
* @param callable $readBodyChunk
*
* @return array
*/
public function executeStreamingRequestWithRetries($opts, $absUrl, $readBodyChunk)
{
/** @var bool */
$shouldRetry = false;
/** @var int */
$numRetries = 0;
// Will contain the bytes of the body of the last request
// if it was not successful and should not be retries
/** @var null|string */
$rbody = null;
// Status code of the last request
/** @var null|bool */
$rcode = null;
// Array of headers from the last request
/** @var null|array */
$lastRHeaders = null;
$errno = null;
$message = null;
$determineWriteCallback = function ($rheaders) use (
&$readBodyChunk,
&$shouldRetry,
&$rbody,
&$numRetries,
&$rcode,
&$lastRHeaders,
&$errno
) {
$lastRHeaders = $rheaders;
$errno = \curl_errno($this->curlHandle);
$rcode = \curl_getinfo($this->curlHandle, \CURLINFO_HTTP_CODE);
// Send the bytes from the body of a successful request to the caller-provided $readBodyChunk.
if ($rcode < 300) {
$rbody = null;
return function ($curl, $data) use (&$readBodyChunk) {
// Don't expose the $curl handle to the user, and don't require them to
// return the length of $data.
\call_user_func_array($readBodyChunk, [$data]);
return \strlen($data);
};
}
$shouldRetry = $this->shouldRetry($errno, $rcode, $rheaders, $numRetries);
// Discard the body from an unsuccessful request that should be retried.
if ($shouldRetry) {
return function ($curl, $data) {
return \strlen($data);
};
} else {
// Otherwise, buffer the body into $rbody. It will need to be parsed to determine
// which exception to throw to the user.
$rbody = '';
return function ($curl, $data) use (&$rbody) {
$rbody .= $data;
return \strlen($data);
};
}
};
while (true) {
list($headerCallback, $writeCallback) = $this->useHeadersToDetermineWriteCallback($opts, $determineWriteCallback);
$opts[\CURLOPT_HEADERFUNCTION] = $headerCallback;
$opts[\CURLOPT_WRITEFUNCTION] = $writeCallback;
$shouldRetry = false;
$rbody = null;
$this->resetCurlHandle();
\curl_setopt_array($this->curlHandle, $opts);
$result = \curl_exec($this->curlHandle);
$errno = \curl_errno($this->curlHandle);
if (0 !== $errno) {
$message = \curl_error($this->curlHandle);
}
if (!$this->getEnablePersistentConnections()) {
$this->closeCurlHandle();
}
if (\is_callable($this->getRequestStatusCallback())) {
\call_user_func_array(
$this->getRequestStatusCallback(),
[$rbody, $rcode, $lastRHeaders, $errno, $message, $shouldRetry, $numRetries]
);
}
if ($shouldRetry) {
++$numRetries;
$sleepSeconds = $this->sleepTime($numRetries, $lastRHeaders);
\usleep((int) ($sleepSeconds * 1000000));
} else {
break;
}
}
if (0 !== $errno) {
$this->handleCurlError($absUrl, $errno, $message, $numRetries);
}
return [$rbody, $rcode, $lastRHeaders];
}
/**
* @param array $opts cURL options
* @param string $absUrl
*/
private function executeRequestWithRetries($opts, $absUrl)
public function executeRequestWithRetries($opts, $absUrl)
{
$numRetries = 0;
@ -296,14 +491,7 @@ class CurlClient implements ClientInterface
// Create a callback to capture HTTP headers for the response
$rheaders = new Util\CaseInsensitiveArray();
$headerCallback = function ($curl, $header_line) use (&$rheaders) {
// Ignore the HTTP request line (HTTP/1.1 200 OK)
if (false === \strpos($header_line, ':')) {
return \strlen($header_line);
}
list($key, $value) = \explode(':', \trim($header_line), 2);
$rheaders[\trim($key)] = \trim($value);
return \strlen($header_line);
return CurlClient::parseLineIntoHeaderArray($header_line, $rheaders);
};
$opts[\CURLOPT_HEADERFUNCTION] = $headerCallback;

View File

@ -0,0 +1,23 @@
<?php
namespace Stripe\HttpClient;
interface StreamingClientInterface
{
/**
* @param string $method The HTTP method being used
* @param string $absUrl The URL being requested, including domain and protocol
* @param array $headers Headers to be used in the request (full strings, not KV pairs)
* @param array $params KV pairs for parameters. Can be nested for arrays and hashes
* @param bool $hasFile Whether or not $params references a file (via an @ prefix or
* CURLFile)
* @param callable $readBodyChunkCallable a function that will be called with chunks of bytes from the body if the request is successful
*
* @throws \Stripe\Exception\ApiConnectionException
* @throws \Stripe\Exception\UnexpectedValueException
*
* @return array an array whose first element is raw request body, second
* element is HTTP status code and third array of HTTP headers
*/
public function requestStream($method, $absUrl, $headers, $params, $hasFile, $readBodyChunkCallable);
}

View File

@ -0,0 +1,45 @@
<?php
// File generated from our OpenAPI spec
namespace Stripe\Identity;
/**
* A VerificationReport is the result of an attempt to collect and verify data from
* a user. The collection of verification checks performed is determined from the
* <code>type</code> and <code>options</code> parameters used. You can find the
* result of each verification check performed in the appropriate sub-resource:
* <code>document</code>, <code>id_number</code>, <code>selfie</code>.
*
* Each VerificationReport contains a copy of any data collected by the user as
* well as reference IDs which can be used to access collected images through the
* <a href="https://stripe.com/docs/api/files">FileUpload</a> API. To configure and
* create VerificationReports, use the <a
* href="https://stripe.com/docs/api/identity/verification_sessions">VerificationSession</a>
* API.
*
* Related guides: <a
* href="https://stripe.com/docs/identity/verification-sessions#results">Accessing
* verification results</a>.
*
* @property string $id Unique identifier for the object.
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property \Stripe\StripeObject $document Result from a document check
* @property \Stripe\StripeObject $id_number Result from an id_number check
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property \Stripe\StripeObject $options
* @property \Stripe\StripeObject $selfie Result from a selfie check
* @property string $type Type of report.
* @property null|string $verification_session ID of the VerificationSession that created this report.
*/
class VerificationReport extends \Stripe\ApiResource
{
const OBJECT_NAME = 'identity.verification_report';
use \Stripe\ApiOperations\All;
use \Stripe\ApiOperations\Retrieve;
const TYPE_DOCUMENT = 'document';
const TYPE_ID_NUMBER = 'id_number';
}

View File

@ -0,0 +1,88 @@
<?php
// File generated from our OpenAPI spec
namespace Stripe\Identity;
/**
* A VerificationSession guides you through the process of collecting and verifying
* the identities of your users. It contains details about the type of
* verification, such as what <a
* href="/docs/identity/verification-checks">verification check</a> to perform.
* Only create one VerificationSession for each verification in your system.
*
* A VerificationSession transitions through <a
* href="/docs/identity/how-sessions-work">multiple statuses</a> throughout its
* lifetime as it progresses through the verification flow. The VerificationSession
* contains the user's verified data after verification checks are complete.
*
* Related guide: <a
* href="https://stripe.com/docs/identity/verification-sessions">The Verification
* Sessions API</a>
*
* @property string $id Unique identifier for the object.
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property null|string $client_secret The short-lived client secret used by Stripe.js to <a href="https://stripe.com/docs/js/identity/modal">show a verification modal</a> inside your app. This client secret expires after 24 hours and can only be used once. Dont store it, log it, embed it in a URL, or expose it to anyone other than the user. Make sure that you have TLS enabled on any page that includes the client secret. Refer to our docs on <a href="https://stripe.com/docs/identity/verification-sessions#client-secret">passing the client secret to the frontend</a> to learn more.
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property null|\Stripe\StripeObject $last_error If present, this property tells you the last error encountered when processing the verification.
* @property null|string|\Stripe\Identity\VerificationReport $last_verification_report ID of the most recent VerificationReport. <a href="https://stripe.com/docs/identity/verification-sessions#results">Learn more about accessing detailed verification results.</a>
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property \Stripe\StripeObject $metadata Set of <a href="https://stripe.com/docs/api/metadata">key-value pairs</a> that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
* @property \Stripe\StripeObject $options
* @property null|\Stripe\StripeObject $redaction Redaction status of this VerificationSession. If the VerificationSession is not redacted, this field will be null.
* @property string $status Status of this VerificationSession. <a href="https://stripe.com/docs/identity/how-sessions-work">Learn more about the lifecycle of sessions</a>.
* @property string $type The type of <a href="https://stripe.com/docs/identity/verification-checks">verification check</a> to be performed.
* @property null|string $url The short-lived URL that you use to redirect a user to Stripe to submit their identity information. This URL expires after 48 hours and can only be used once. Dont store it, log it, send it in emails or expose it to anyone other than the user. Refer to our docs on <a href="https://stripe.com/docs/identity/verify-identity-documents?platform=web&amp;type=redirect">verifying identity documents</a> to learn how to redirect users to Stripe.
* @property null|\Stripe\StripeObject $verified_outputs The users verified data.
*/
class VerificationSession extends \Stripe\ApiResource
{
const OBJECT_NAME = 'identity.verification_session';
use \Stripe\ApiOperations\All;
use \Stripe\ApiOperations\Create;
use \Stripe\ApiOperations\Retrieve;
use \Stripe\ApiOperations\Update;
const STATUS_CANCELED = 'canceled';
const STATUS_PROCESSING = 'processing';
const STATUS_REQUIRES_INPUT = 'requires_input';
const STATUS_VERIFIED = 'verified';
const TYPE_DOCUMENT = 'document';
const TYPE_ID_NUMBER = 'id_number';
/**
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Identity\VerificationSession the canceled verification session
*/
public function cancel($params = null, $opts = null)
{
$url = $this->instanceUrl() . '/cancel';
list($response, $opts) = $this->_request('post', $url, $params, $opts);
$this->refreshFrom($response, $opts);
return $this;
}
/**
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Identity\VerificationSession the redacted verification session
*/
public function redact($params = null, $opts = null)
{
$url = $this->instanceUrl() . '/redact';
list($response, $opts) = $this->_request('post', $url, $params, $opts);
$this->refreshFrom($response, $opts);
return $this;
}
}

View File

@ -23,7 +23,7 @@ namespace Stripe;
* to finalize the invoice.
*
* If your invoice is configured to be billed by sending an email, then based on
* your <a href="https://dashboard.stripe.com/account/billing/automatic'">email
* your <a href="https://dashboard.stripe.com/account/billing/automatic">email
* settings</a>, Stripe will email the invoice to your customer and await payment.
* These emails can contain a link to a hosted page to pay the invoice.
*
@ -41,25 +41,28 @@ namespace Stripe;
* Related guide: <a href="https://stripe.com/docs/billing/invoices/sending">Send
* Invoices to Customers</a>.
*
* @property string $id Unique identifier for the object.
* @property string $id Unique identifier for the object. This property is always present unless the invoice is an upcoming invoice. See <a href="https://stripe.com/docs/api/invoices/upcoming">Retrieve an upcoming invoice</a> for more details.
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property null|string $account_country The country of the business associated with this invoice, most often the business creating the invoice.
* @property null|string $account_name The public name of the business associated with this invoice, most often the business creating the invoice.
* @property null|(string|\Stripe\TaxId)[] $account_tax_ids The account tax IDs associated with the invoice. Only editable when the invoice is a draft.
* @property int $amount_due Final amount due at this time for this invoice. If the invoice's total is smaller than the minimum charge amount, for example, or if there is account credit that can be applied to the invoice, the <code>amount_due</code> may be 0. If there is a positive <code>starting_balance</code> for the invoice (the customer owes money), the <code>amount_due</code> will also take that into account. The charge that gets generated for the invoice will be for the amount specified in <code>amount_due</code>.
* @property int $amount_paid The amount, in %s, that was paid.
* @property int $amount_remaining The amount remaining, in %s, that is due.
* @property int $amount_remaining The difference between amount_due and amount_paid, in %s.
* @property int $amount_shipping This is the sum of all the shipping amounts.
* @property null|string|\Stripe\StripeObject $application ID of the Connect Application that created the invoice.
* @property null|int $application_fee_amount The fee in %s that will be applied to the invoice and transferred to the application owner's Stripe account when the invoice is paid.
* @property int $attempt_count Number of payment attempts made for this invoice, from the perspective of the payment retry schedule. Any payment attempt counts as the first attempt, and subsequently only automatic retries increment the attempt count. In other words, manual payment attempts after the first attempt do not affect the retry schedule.
* @property bool $attempted Whether an attempt has been made to pay the invoice. An invoice is not attempted until 1 hour after the <code>invoice.created</code> webhook, for example, so you might not want to display that invoice as unpaid to your users.
* @property bool $auto_advance Controls whether Stripe will perform <a href="https://stripe.com/docs/billing/invoices/workflow/#auto_advance">automatic collection</a> of the invoice. When <code>false</code>, the invoice's state will not automatically advance without an explicit action.
* @property \Stripe\StripeObject $automatic_tax
* @property null|string $billing_reason Indicates the reason why the invoice was created. <code>subscription_cycle</code> indicates an invoice created by a subscription advancing into a new period. <code>subscription_create</code> indicates an invoice created due to creating a subscription. <code>subscription_update</code> indicates an invoice created due to updating a subscription. <code>subscription</code> is set for all old invoices to indicate either a change to a subscription or a period advancement. <code>manual</code> is set for all invoices unrelated to a subscription (for example: created via the invoice editor). The <code>upcoming</code> value is reserved for simulated invoices per the upcoming invoice endpoint. <code>subscription_threshold</code> indicates an invoice created due to a billing threshold being reached.
* @property null|string|\Stripe\Charge $charge ID of the latest charge generated for this invoice, if any.
* @property null|string $collection_method Either <code>charge_automatically</code>, or <code>send_invoice</code>. When charging automatically, Stripe will attempt to pay this invoice using the default source attached to the customer. When sending an invoice, Stripe will email this invoice to the customer with payment instructions.
* @property string $collection_method Either <code>charge_automatically</code>, or <code>send_invoice</code>. When charging automatically, Stripe will attempt to pay this invoice using the default source attached to the customer. When sending an invoice, Stripe will email this invoice to the customer with payment instructions.
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property string $currency Three-letter <a href="https://www.iso.org/iso-4217-currency-codes.html">ISO currency code</a>, in lowercase. Must be a <a href="https://stripe.com/docs/currencies">supported currency</a>.
* @property null|\Stripe\StripeObject[] $custom_fields Custom fields displayed on the invoice.
* @property string|\Stripe\Customer $customer The ID of the customer who will be billed.
* @property null|string|\Stripe\Customer $customer The ID of the customer who will be billed.
* @property null|\Stripe\StripeObject $customer_address The customer's address. Until the invoice is finalized, this field will equal <code>customer.address</code>. Once the invoice is finalized, this field will no longer be updated.
* @property null|string $customer_email The customer's email. Until the invoice is finalized, this field will equal <code>customer.email</code>. Once the invoice is finalized, this field will no longer be updated.
* @property null|string $customer_name The customer's name. Until the invoice is finalized, this field will equal <code>customer.name</code>. Once the invoice is finalized, this field will no longer be updated.
@ -68,7 +71,7 @@ namespace Stripe;
* @property null|string $customer_tax_exempt The customer's tax exempt status. Until the invoice is finalized, this field will equal <code>customer.tax_exempt</code>. Once the invoice is finalized, this field will no longer be updated.
* @property null|\Stripe\StripeObject[] $customer_tax_ids The customer's tax IDs. Until the invoice is finalized, this field will contain the same tax IDs as <code>customer.tax_ids</code>. Once the invoice is finalized, this field will no longer be updated.
* @property null|string|\Stripe\PaymentMethod $default_payment_method ID of the default payment method for the invoice. It must belong to the customer associated with the invoice. If not set, defaults to the subscription's default payment method, if any, or to the default payment method in the customer's invoice settings.
* @property null|string|\Stripe\Account|\Stripe\AlipayAccount|\Stripe\BankAccount|\Stripe\BitcoinReceiver|\Stripe\Card|\Stripe\Source $default_source ID of the default payment source for the invoice. It must belong to the customer associated with the invoice and be in a chargeable state. If not set, defaults to the subscription's default source, if any, or to the customer's default source.
* @property null|string|\Stripe\Account|\Stripe\BankAccount|\Stripe\Card|\Stripe\Source $default_source ID of the default payment source for the invoice. It must belong to the customer associated with the invoice and be in a chargeable state. If not set, defaults to the subscription's default source, if any, or to the customer's default source.
* @property \Stripe\TaxRate[] $default_tax_rates The tax rates applied to this invoice, if any.
* @property null|string $description An arbitrary string attached to the object. Often useful for displaying to users. Referenced as 'memo' in the Dashboard.
* @property null|\Stripe\Discount $discount Describes the current discount applied to this invoice, if there is one. Not populated if there are multiple discounts.
@ -76,34 +79,46 @@ namespace Stripe;
* @property null|int $due_date The date on which payment for this invoice is due. This value will be <code>null</code> for invoices where <code>collection_method=charge_automatically</code>.
* @property null|int $ending_balance Ending customer balance after the invoice is finalized. Invoices are finalized approximately an hour after successful webhook delivery or when payment collection is attempted for the invoice. If the invoice has not been finalized yet, this will be null.
* @property null|string $footer Footer displayed on the invoice.
* @property null|\Stripe\StripeObject $from_invoice Details of the invoice that was cloned. See the <a href="https://stripe.com/docs/invoicing/invoice-revisions">revision documentation</a> for more details.
* @property null|string $hosted_invoice_url The URL for the hosted invoice page, which allows customers to view and pay an invoice. If the invoice has not been finalized yet, this will be null.
* @property null|string $invoice_pdf The link to download the PDF for the invoice. If the invoice has not been finalized yet, this will be null.
* @property null|\Stripe\ErrorObject $last_finalization_error The error encountered during the previous attempt to finalize the invoice. This field is cleared when the invoice is successfully finalized.
* @property \Stripe\Collection $lines The individual line items that make up the invoice. <code>lines</code> is sorted as follows: invoice items in reverse chronological order, followed by the subscription, if any.
* @property null|\Stripe\StripeObject $last_finalization_error The error encountered during the previous attempt to finalize the invoice. This field is cleared when the invoice is successfully finalized.
* @property null|string|\Stripe\Invoice $latest_revision The ID of the most recent non-draft revision of this invoice
* @property \Stripe\Collection<\Stripe\InvoiceLineItem> $lines The individual line items that make up the invoice. <code>lines</code> is sorted as follows: invoice items in reverse chronological order, followed by the subscription, if any.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property null|\Stripe\StripeObject $metadata Set of <a href="https://stripe.com/docs/api/metadata">key-value pairs</a> that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
* @property null|int $next_payment_attempt The time at which payment will next be attempted. This value will be <code>null</code> for invoices where <code>collection_method=send_invoice</code>.
* @property null|string $number A unique, identifying string that appears on emails sent to the customer for this invoice. This starts with the customer's unique invoice_prefix if it is specified.
* @property null|string|\Stripe\Account $on_behalf_of The account (if any) for which the funds of the invoice payment are intended. If set, the invoice will be presented with the branding and support information of the specified account. See the <a href="https://stripe.com/docs/billing/invoices/connect">Invoices with Connect</a> documentation for details.
* @property bool $paid Whether payment was successfully collected for this invoice. An invoice can be paid (most commonly) with a charge or with credit from the customer's account balance.
* @property bool $paid_out_of_band Returns true if the invoice was manually marked paid, returns false if the invoice hasn't been paid yet or was paid on Stripe.
* @property null|string|\Stripe\PaymentIntent $payment_intent The PaymentIntent associated with this invoice. The PaymentIntent is generated when the invoice is finalized, and can then be used to pay the invoice. Note that voiding an invoice will cancel the PaymentIntent.
* @property \Stripe\StripeObject $payment_settings
* @property int $period_end End of the usage period during which invoice items were added to this invoice.
* @property int $period_start Start of the usage period during which invoice items were added to this invoice.
* @property int $post_payment_credit_notes_amount Total amount of all post-payment credit notes issued for this invoice.
* @property int $pre_payment_credit_notes_amount Total amount of all pre-payment credit notes issued for this invoice.
* @property null|string|\Stripe\Quote $quote The quote this invoice was generated from.
* @property null|string $receipt_number This is the transaction number that appears on email receipts sent for this invoice.
* @property int $starting_balance Starting customer balance before the invoice is finalized. If the invoice has not been finalized yet, this will be the current customer balance.
* @property null|\Stripe\StripeObject $rendering_options Options for invoice PDF rendering.
* @property null|\Stripe\StripeObject $shipping_cost The details of the cost of shipping, including the ShippingRate applied on the invoice.
* @property null|\Stripe\StripeObject $shipping_details Shipping details for the invoice. The Invoice PDF will use the <code>shipping_details</code> value if it is set, otherwise the PDF will render the shipping address from the customer.
* @property int $starting_balance Starting customer balance before the invoice is finalized. If the invoice has not been finalized yet, this will be the current customer balance. For revision invoices, this also includes any customer balance that was applied to the original invoice.
* @property null|string $statement_descriptor Extra information about an invoice for the customer's credit card statement.
* @property null|string $status The status of the invoice, one of <code>draft</code>, <code>open</code>, <code>paid</code>, <code>uncollectible</code>, or <code>void</code>. <a href="https://stripe.com/docs/billing/invoices/workflow#workflow-overview">Learn more</a>
* @property \Stripe\StripeObject $status_transitions
* @property null|string|\Stripe\Subscription $subscription The subscription that this invoice was prepared for, if any.
* @property int $subscription_proration_date Only set for upcoming invoices that preview prorations. The time used to calculate prorations.
* @property int $subtotal Total of all subscriptions, invoice items, and prorations on the invoice before any invoice level discount or tax is applied. Item discounts are already incorporated
* @property int $subtotal Total of all subscriptions, invoice items, and prorations on the invoice before any invoice level discount or exclusive tax is applied. Item discounts are already incorporated
* @property null|int $subtotal_excluding_tax The integer amount in %s representing the subtotal of the invoice before any invoice level discount or tax is applied. Item discounts are already incorporated
* @property null|int $tax The amount of tax on this invoice. This is the sum of all the tax amounts on this invoice.
* @property null|string|\Stripe\TestHelpers\TestClock $test_clock ID of the test clock this invoice belongs to.
* @property \Stripe\StripeObject $threshold_reason
* @property int $total Total after discounts and taxes.
* @property null|\Stripe\StripeObject[] $total_discount_amounts The aggregate amounts calculated per discount across all line items.
* @property null|int $total_excluding_tax The integer amount in %s representing the total amount of the invoice including all discounts but excluding all tax.
* @property \Stripe\StripeObject[] $total_tax_amounts The aggregate amounts calculated per tax rate for all line items.
* @property null|\Stripe\StripeObject $transfer_data The account (if any) the payment will be attributed to for tax reporting, and where funds from the payment will be transferred to for the invoice.
* @property null|int $webhooks_delivered_at Invoices are automatically paid or sent 1 hour after webhooks are delivered, or until all webhook delivery attempts have <a href="https://stripe.com/docs/billing/webhooks#understand">been exhausted</a>. This field tracks the time when webhooks for this invoice were successfully delivered. If the invoice had no webhooks to deliver, this will be set while the invoice is being created.
*/
class Invoice extends ApiResource
@ -113,13 +128,17 @@ class Invoice extends ApiResource
use ApiOperations\All;
use ApiOperations\Create;
use ApiOperations\Delete;
use ApiOperations\NestedResource;
use ApiOperations\Retrieve;
use ApiOperations\Search;
use ApiOperations\Update;
const BILLING_CHARGE_AUTOMATICALLY = 'charge_automatically';
const BILLING_SEND_INVOICE = 'send_invoice';
const BILLING_REASON_AUTOMATIC_PENDING_INVOICE_ITEM_INVOICE = 'automatic_pending_invoice_item_invoice';
const BILLING_REASON_MANUAL = 'manual';
const BILLING_REASON_QUOTE_ACCEPT = 'quote_accept';
const BILLING_REASON_SUBSCRIPTION = 'subscription';
const BILLING_REASON_SUBSCRIPTION_CREATE = 'subscription_create';
const BILLING_REASON_SUBSCRIPTION_CYCLE = 'subscription_cycle';
@ -137,49 +156,13 @@ class Invoice extends ApiResource
const STATUS_UNCOLLECTIBLE = 'uncollectible';
const STATUS_VOID = 'void';
use ApiOperations\NestedResource;
const PATH_LINES = '/lines';
/**
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Invoice the upcoming invoice
*/
public static function upcoming($params = null, $opts = null)
{
$url = static::classUrl() . '/upcoming';
list($response, $opts) = static::_staticRequest('get', $url, $params, $opts);
$obj = Util\Util::convertToStripeObject($response->json, $opts);
$obj->setLastResponse($response);
return $obj;
}
/**
* @param string $id the ID of the invoice on which to retrieve the lines
* @param null|array $params
* @param null|array|string $opts
*
* @throws StripeExceptionApiErrorException if the request fails
*
* @return \Stripe\Collection the list of lines (InvoiceLineItem)
*/
public static function allLines($id, $params = null, $opts = null)
{
return self::_allNestedResources($id, static::PATH_LINES, $params, $opts);
}
/**
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return Invoice the finalized invoice
* @return \Stripe\Invoice the finalized invoice
*/
public function finalizeInvoice($params = null, $opts = null)
{
@ -196,7 +179,7 @@ class Invoice extends ApiResource
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return Invoice the uncollectible invoice
* @return \Stripe\Invoice the uncollectible invoice
*/
public function markUncollectible($params = null, $opts = null)
{
@ -213,7 +196,7 @@ class Invoice extends ApiResource
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return Invoice the paid invoice
* @return \Stripe\Invoice the paid invoice
*/
public function pay($params = null, $opts = null)
{
@ -230,7 +213,7 @@ class Invoice extends ApiResource
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return Invoice the sent invoice
* @return \Stripe\Invoice the sent invoice
*/
public function sendInvoice($params = null, $opts = null)
{
@ -247,7 +230,43 @@ class Invoice extends ApiResource
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return Invoice the voided invoice
* @return \Stripe\Invoice the upcoming invoice
*/
public static function upcoming($params = null, $opts = null)
{
$url = static::classUrl() . '/upcoming';
list($response, $opts) = static::_staticRequest('get', $url, $params, $opts);
$obj = \Stripe\Util\Util::convertToStripeObject($response->json, $opts);
$obj->setLastResponse($response);
return $obj;
}
/**
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Collection<\Stripe\InvoiceLineItem> list of InvoiceLineItems
*/
public static function upcomingLines($params = null, $opts = null)
{
$url = static::classUrl() . '/upcoming/lines';
list($response, $opts) = static::_staticRequest('get', $url, $params, $opts);
$obj = \Stripe\Util\Util::convertToStripeObject($response->json, $opts);
$obj->setLastResponse($response);
return $obj;
}
/**
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Invoice the voided invoice
*/
public function voidInvoice($params = null, $opts = null)
{
@ -257,4 +276,35 @@ class Invoice extends ApiResource
return $this;
}
/**
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\SearchResult<Invoice> the invoice search results
*/
public static function search($params = null, $opts = null)
{
$url = '/v1/invoices/search';
return self::_searchResource($url, $params, $opts);
}
const PATH_LINES = '/lines';
/**
* @param string $id the ID of the invoice on which to retrieve the line items
* @param null|array $params
* @param null|array|string $opts
*
* @throws \Stripe\Exception\ApiErrorException if the request fails
*
* @return \Stripe\Collection<\Stripe\LineItem> the list of line items
*/
public static function allLines($id, $params = null, $opts = null)
{
return self::_allNestedResources($id, static::PATH_LINES, $params, $opts);
}
}

View File

@ -34,6 +34,7 @@ namespace Stripe;
* @property null|string|\Stripe\Subscription $subscription The subscription that this invoice item has been created for, if any.
* @property string $subscription_item The subscription item that this invoice item has been created for, if any.
* @property null|\Stripe\TaxRate[] $tax_rates The tax rates which apply to the invoice item. When set, the <code>default_tax_rates</code> on the invoice do not apply to this invoice item.
* @property null|string|\Stripe\TestHelpers\TestClock $test_clock ID of the test clock this invoice item belongs to.
* @property null|int $unit_amount Unit amount (in the <code>currency</code> specified) of the invoice item.
* @property null|string $unit_amount_decimal Same as <code>unit_amount</code>, but contains a decimal value with at most 12 decimal places.
*/

Some files were not shown because too many files have changed in this diff Show More