use crate::Error;
pub async fn capture(
payment_intent_id: &str,
amount_cents: Option<i64>,
) -> Result<stripe::PaymentIntent, Error> {
let _id: stripe::PaymentIntentId = payment_intent_id
.parse()
.map_err(|_| Error::Stripe(format!("invalid payment intent id: {payment_intent_id}")))?;
let amount_to_capture = match amount_cents {
None => None,
Some(n) if n <= 0 => {
return Err(Error::Stripe(
"amount_to_capture must be positive".to_string(),
))
}
Some(n) => Some(
u64::try_from(n)
.map_err(|_| Error::Stripe("amount_to_capture must be positive".to_string()))?,
),
};
let client = crate::Stripe::client();
let params = stripe::CapturePaymentIntent {
amount_to_capture,
..Default::default()
};
let pi = stripe::PaymentIntent::capture(client, payment_intent_id, params).await?;
Ok(pi)
}
pub async fn cancel(payment_intent_id: &str) -> Result<stripe::PaymentIntent, Error> {
let _id: stripe::PaymentIntentId = payment_intent_id
.parse()
.map_err(|_| Error::Stripe(format!("invalid payment intent id: {payment_intent_id}")))?;
let client = crate::Stripe::client();
let params = stripe::CancelPaymentIntent::default();
let pi = stripe::PaymentIntent::cancel(client, payment_intent_id, params).await?;
Ok(pi)
}
pub async fn retrieve(payment_intent_id: &str) -> Result<stripe::PaymentIntent, Error> {
let id: stripe::PaymentIntentId = payment_intent_id
.parse()
.map_err(|_| Error::Stripe(format!("invalid payment intent id: {payment_intent_id}")))?;
let client = crate::Stripe::client();
let pi = stripe::PaymentIntent::retrieve(client, &id, &[]).await?;
Ok(pi)
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn capture_rejects_invalid_id_before_network() {
let result = capture("not-a-valid-pi-id", None).await;
assert!(
matches!(result, Err(Error::Stripe(ref m)) if m.contains("invalid payment intent id")),
"expected invalid-id error, got {result:?}"
);
}
#[tokio::test]
async fn capture_rejects_negative_amount() {
let result = capture("pi_test_123", Some(-5)).await;
assert!(
matches!(result, Err(Error::Stripe(ref m)) if m.contains("must be positive")),
"expected positive-amount error, got {result:?}"
);
}
#[tokio::test]
async fn capture_rejects_zero_amount() {
let result = capture("pi_test_123", Some(0)).await;
assert!(
matches!(result, Err(Error::Stripe(ref m)) if m.contains("must be positive")),
"expected positive-amount error for zero, got {result:?}"
);
}
#[tokio::test]
async fn cancel_rejects_invalid_id_before_network() {
let result = cancel("bad id with spaces").await;
assert!(
matches!(result, Err(Error::Stripe(ref m)) if m.contains("invalid payment intent id")),
"expected invalid-id error, got {result:?}"
);
}
#[tokio::test]
async fn retrieve_rejects_invalid_id_before_network() {
let result = retrieve("").await;
assert!(
matches!(result, Err(Error::Stripe(ref m)) if m.contains("invalid payment intent id")),
"expected invalid-id error, got {result:?}"
);
}
}