diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index e892105f..a45a5cc0 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -4,8 +4,4 @@ on:
   push: { branches: [ main ] }
 jobs:
   unit-tests:
-    uses: vapor/ci/.github/workflows/run-unit-tests.yml@reusable-workflows
-    with:
-      with_coverage: false
-      with_tsan: true
-      coverage_ignores: '/Tests/'
+    uses: vapor/ci/.github/workflows/run-unit-tests.yml@main
diff --git a/Package.swift b/Package.swift
index 54adf5bb..8a3c05cf 100644
--- a/Package.swift
+++ b/Package.swift
@@ -14,7 +14,7 @@ let package = Package(
     ],
     dependencies: [
         .package(url: "https://github.com/swift-server/async-http-client.git", from: "1.1.0"),
-        .package(url: "https://github.com/apple/swift-crypto.git", "1.0.0" ..< "3.0.0"),
+        .package(url: "https://github.com/apple/swift-crypto.git", "1.0.0" ..< "4.0.0"),
     ],
     targets: [
         .target(name: "StripeKit", dependencies: [
diff --git a/Sources/StripeKit/Core Resources/Charges/ChargePaymentMethods.swift b/Sources/StripeKit/Core Resources/Charges/ChargePaymentMethods.swift
index 263e7926..4e68a9c1 100644
--- a/Sources/StripeKit/Core Resources/Charges/ChargePaymentMethods.swift	
+++ b/Sources/StripeKit/Core Resources/Charges/ChargePaymentMethods.swift	
@@ -235,6 +235,8 @@ public struct ChargePaymentMethodDetailsBoleto: Codable {
 public struct ChargePaymentMethodDetailsCard: Codable {
     /// Card brand. Can be `amex`, `diners`, `discover`, `jcb`, `mastercard`, `unionpay`, `visa`, or `unknown`.
     public var brand: PaymentMethodDetailsCardBrand?
+    /// When using manual capture, a future timestamp after which the charge will be automatically refunded if uncaptured.
+    public var captureBefore: Date?
     /// Check results by Card networks on Card address and CVC at time of payment.
     public var checks: PaymentMethodDetailsCardChecks?
     /// Two-letter ISO code representing the country of the card. You could use this attribute to get a sense of the international breakdown of cards you’ve collected.
@@ -259,6 +261,7 @@ public struct ChargePaymentMethodDetailsCard: Codable {
     public var wallet: ChargePaymentMethodDetailsCardWallet?
     
     public init(brand: PaymentMethodDetailsCardBrand? = nil,
+                captureBefore: Date? = nil,
                 checks: PaymentMethodDetailsCardChecks? = nil,
                 country: String? = nil,
                 expMonth: Int? = nil,
@@ -271,6 +274,7 @@ public struct ChargePaymentMethodDetailsCard: Codable {
                 threeDSecure: ChargePaymentMethodDetailsCardThreeDSecure? = nil,
                 wallet: ChargePaymentMethodDetailsCardWallet? = nil) {
         self.brand = brand
+        self.captureBefore = captureBefore
         self.checks = checks
         self.country = country
         self.expMonth = expMonth
diff --git a/Sources/StripeKit/Core Resources/Events/Event.swift b/Sources/StripeKit/Core Resources/Events/Event.swift
index dec095ab..49294408 100644
--- a/Sources/StripeKit/Core Resources/Events/Event.swift	
+++ b/Sources/StripeKit/Core Resources/Events/Event.swift	
@@ -235,7 +235,114 @@ public enum EventObject: Codable {
         }
     }
     
-    public func encode(to encoder: Encoder) throws { }
+    public func encode(to encoder: Encoder) throws {
+        switch self {
+        case .account(let connectAccount):
+            try connectAccount.encode(to: encoder)
+        case .application(let connectApplication):
+            try connectApplication.encode(to: encoder)
+        case .card(let card):
+            try card.encode(to: encoder)
+        case .cashBalance(let cashBalance):
+            try cashBalance.encode(to: encoder)
+        case .bankAccount(let bankAccount):
+            try bankAccount.encode(to: encoder)
+        case .applicationFee(let applicationFee):
+            try applicationFee.encode(to: encoder)
+        case .applicationFeeRefund(let applicationFeeRefund):
+            try applicationFeeRefund.encode(to: encoder)
+        case .balance(let balance):
+            try balance.encode(to: encoder)
+        case .capability(let capability):
+            try capability.encode(to: encoder)
+        case .charge(let charge):
+            try charge.encode(to: encoder)
+        case .dispute(let dispute):
+            try dispute.encode(to: encoder)
+        case .refund(let refund):
+            try refund.encode(to: encoder)
+        case .checkoutSession(let session):
+            try session.encode(to: encoder)
+        case .configuration(let portalConfiguration):
+            try portalConfiguration.encode(to: encoder)
+        case .coupon(let coupon):
+            try coupon.encode(to: encoder)
+        case .creditNote(let creditNote):
+            try creditNote.encode(to: encoder)
+        case .customer(let customer):
+            try customer.encode(to: encoder)
+        case .discount(let discount):
+            try discount.encode(to: encoder)
+        case .subscription(let subscription):
+            try subscription.encode(to: encoder)
+        case .taxId(let taxID):
+            try taxID.encode(to: encoder)
+        case .file(let file):
+            try file.encode(to: encoder)
+        case .invoice(let invoice):
+            try invoice.encode(to: encoder)
+        case .invoiceItem(let invoiceItem):
+            try invoiceItem.encode(to: encoder)
+        case .issuingAuthorization(let authorization):
+            try authorization.encode(to: encoder)
+        case .issuingCard(let issuingCard):
+            try issuingCard.encode(to: encoder)
+        case .issuingCardHolder(let cardholder):
+            try cardholder.encode(to: encoder)
+        case .issuingDispute(let issuingDispute):
+            try issuingDispute.encode(to: encoder)
+        case .issuingTransaction(let transaction):
+            try transaction.encode(to: encoder)
+        case .mandate(let mandate):
+            try mandate.encode(to: encoder)
+        case .paymentIntent(let paymentIntent):
+            try paymentIntent.encode(to: encoder)
+        case .paymentLink(let paymentLink):
+            try paymentLink.encode(to: encoder)
+        case .paymentMethod(let paymentMethod):
+            try paymentMethod.encode(to: encoder)
+        case .payout(let payout):
+            try payout.encode(to: encoder)
+        case .person(let person):
+            try person.encode(to: encoder)
+        case .plan(let plan):
+            try plan.encode(to: encoder)
+        case .price(let price):
+            try price.encode(to: encoder)
+        case .product(let product):
+            try product.encode(to: encoder)
+        case .promotionCode(let promotionCode):
+            try promotionCode.encode(to: encoder)
+        case .earlyFraudWarniing(let earlyFraudWarning):
+            try earlyFraudWarning.encode(to: encoder)
+        case .quote(let quote):
+            try quote.encode(to: encoder)
+        case .reportRun(let reportRun):
+            try reportRun.encode(to: encoder)
+        case .reportType(let reportType):
+            try reportType.encode(to: encoder)
+        case .review(let review):
+            try review.encode(to: encoder)
+        case .setupIntent(let setupIntent):
+            try setupIntent.encode(to: encoder)
+        case .scheduledQueryRun(let scheduledQueryRun):
+            try scheduledQueryRun.encode(to: encoder)
+        case .subscriptionSchedule(let subscriptionSchedule):
+            try subscriptionSchedule.encode(to: encoder)
+        case .taxRate(let taxRate):
+            try taxRate.encode(to: encoder)
+        case .topup(let topUp):
+            try topUp.encode(to: encoder)
+        case .transfer(let transfer):
+            try transfer.encode(to: encoder)
+        case .testClock(let testClock):
+            try testClock.encode(to: encoder)
+        case .reader(let terminalReader):
+            try terminalReader.encode(to: encoder)
+        case .verificationSession(let verificationSession):
+            try verificationSession.encode(to: encoder)
+        }
+    }
     
     private enum CodingKeys: String, CodingKey {
         case object
diff --git a/Sources/StripeKit/Core Resources/PaymentIntents/PaymentIntent.swift b/Sources/StripeKit/Core Resources/PaymentIntents/PaymentIntent.swift
index e2289e1d..c691d41c 100644
--- a/Sources/StripeKit/Core Resources/PaymentIntents/PaymentIntent.swift	
+++ b/Sources/StripeKit/Core Resources/PaymentIntents/PaymentIntent.swift	
@@ -238,6 +238,7 @@ public enum PaymentIntentCancellationReason: String, Codable {
 public enum PaymentIntentCaptureMethod: String, Codable {
     /// (Default) Stripe automatically captures funds when the customer authorizes the payment.
     case automatic
+    case automaticAsync = "automatic_async"
     /// Place a hold on the funds when the customer authorizes the payment, but don’t capture the funds until later. (Not all payment methods support this.)
     case manual
 }
diff --git a/Sources/StripeKit/Shared Models/Currency.swift b/Sources/StripeKit/Shared Models/Currency.swift
index e3fcffc1..6f49c8be 100644
--- a/Sources/StripeKit/Shared Models/Currency.swift	
+++ b/Sources/StripeKit/Shared Models/Currency.swift	
@@ -6,7 +6,7 @@
 //
 //
 
-public enum Currency: String, Codable {
+public enum Currency: String, Codable, CaseIterable {
     case usd
     case aed
     case afn