jnbt / candy_check

Check and verify in-app receipts
MIT License
125 stars 70 forks source link

Add support to ios 7 style grand unified receipts #16

Closed zabolotnov87 closed 3 years ago

zabolotnov87 commented 7 years ago

The PR adds classes to work with ios 7 style grand unified receips: Unified::AppReceipt and Unified::InAppReceipt.

coveralls commented 7 years ago

Coverage Status

Coverage decreased (-0.8%) to 97.786% when pulling 6a0b1904818e8bfd581ed02f0c1764827b144fa2 on hello-baby:support-unified-receipts into a61a68935c9aef8c0ac72e47b7b56c2451fb206f on jnbt:master.

coveralls commented 7 years ago

Coverage Status

Coverage increased (+0.9%) to 99.404% when pulling 6a0b1904818e8bfd581ed02f0c1764827b144fa2 on hello-baby:support-unified-receipts into a61a68935c9aef8c0ac72e47b7b56c2451fb206f on jnbt:master.

coveralls commented 7 years ago

Coverage Status

Coverage decreased (-0.8%) to 97.786% when pulling c6b3cd1eb7be3f833baaea73750e4145a09f5534 on hello-baby:support-unified-receipts into a61a68935c9aef8c0ac72e47b7b56c2451fb206f on jnbt:master.

coveralls commented 7 years ago

Coverage Status

Coverage decreased (-0.8%) to 97.786% when pulling ce27aaf4bd668b43e9adde2aefd9f37acde79196 on hello-baby:support-unified-receipts into a61a68935c9aef8c0ac72e47b7b56c2451fb206f on jnbt:master.

coveralls commented 7 years ago

Coverage Status

Coverage increased (+0.1%) to 98.65% when pulling eedde53569bb4418f47b4eebbce31584a2d21dfe on hello-baby:support-unified-receipts into a61a68935c9aef8c0ac72e47b7b56c2451fb206f on jnbt:master.

coveralls commented 7 years ago

Coverage Status

Coverage increased (+1.4%) to 99.935% when pulling eedde53569bb4418f47b4eebbce31584a2d21dfe on hello-baby:support-unified-receipts into a61a68935c9aef8c0ac72e47b7b56c2451fb206f on jnbt:master.

coveralls commented 7 years ago

Coverage Status

Coverage increased (+1.4%) to 99.935% when pulling eedde53569bb4418f47b4eebbce31584a2d21dfe on hello-baby:support-unified-receipts into a61a68935c9aef8c0ac72e47b7b56c2451fb206f on jnbt:master.

coveralls commented 7 years ago

Coverage Status

Coverage increased (+1.4%) to 99.935% when pulling eedde53569bb4418f47b4eebbce31584a2d21dfe on hello-baby:support-unified-receipts into a61a68935c9aef8c0ac72e47b7b56c2451fb206f on jnbt:master.

jnbt commented 7 years ago

@zabolotnov87 Thanks for your work. It looks quite great. Maybe we should think about dropping support for the iOS6 style receipts at all.

As also mentioned in #15: I'm currently in a situation where I cannot work on this project for a couple of weeks. I'm very sorry for this, but my family goes first. I'll check this PR as soon as possible.

julianhirt commented 6 years ago

Any updates on this issue?

antonwestman commented 6 years ago

Nice to have you back @jnbt.

So, apparently these extra fields are presented outside of the receipt under the pending_renewal_info-key.

"pending_renewal_info": 
  [{"expiration_intent"=>"1",
    "auto_renew_product_id"=>"com.fishbrain.dev.monthly_notrial_799",
    "original_transaction_id"=>"1000000348868401",
    "is_in_billing_retry_period"=>"0",
    "product_id"=>"com.fishbrain.dev.monthly_notrial_799",
    "auto_renew_status"=>"0"},
   {"expiration_intent"=>"1",
    "auto_renew_product_id"=>
     "com.fishbrain.dev.subscription_1_month_30_days_trial",
    "original_transaction_id"=>"1000000348903541",
    "is_in_billing_retry_period"=>"0",
    "product_id"=>"com.fishbrain.dev.subscription_1_month_30_days_trial",
    "auto_renew_status"=>"0"}],

We've solved this in our fork by attaching the renewal info to the last transaction/receipts.

module CandyCheck
  module AppStore
    # Store multiple {Receipt}s in order to perform collective operation on them
    class ReceiptCollection

      PENDING_RENEWAL_INFO_KEYS = %w(expiration_intent
                                     is_in_billing_retry_period
                                     auto_renew_status
                                     auto_renew_product_id).freeze

      # Initializes a new instance which bases on a JSON result
      # from Apple's verification server
      # @param attributes [Array<Hash>]
      def initialize(attributes, pending_renewal_info = nil)
        @attributes = attributes
        @pending_renewal_info = pending_renewal_info
      end

      # Check if the latest expiration date is passed
      # @return [bool]
      def expired?
        expires_at.to_time <= Time.now.utc
      end

      # Check if in trial
      # @return [bool]
      def trial?
        latest_expiring_receipt.is_trial_period
      end

      # Get latest expiration date
      # @return [DateTime]
      def expires_at
        latest_expiring_receipt.expires_date
      end

      # Get number of overdue days. If this is negative, it is not overdue.
      # @return [Integer]
      def overdue_days
        (Date.today - expires_at.to_date).to_i
      end

      # Multiple receipts as in verfication response
      # @return [Array<Unified::InAppReceipt>]
      def receipts
        @receipts ||= receipt_data.map { |r| Unified::InAppReceipt.new(r) }
      end

      private

      def latest_expiring_receipt
        receipts.sort_by(&:expires_date).last
      end

      def receipt_data
        return @attributes unless @pending_renewal_info.present?

        @attributes.group_by{ |r| r['original_transaction_id']}.map do |original_transaction_id, transactions|
          extra_info = @pending_renewal_info.find do |info|
            info["original_transaction_id"] == original_transaction_id
          end.try(:slice, *PENDING_RENEWAL_INFO_KEYS)
          transactions.last.merge! extra_info
          transactions
        end.flatten
      end
    end
  end
end
zabolotnov87 commented 6 years ago

Updated.

coveralls commented 6 years ago

Coverage Status

Coverage increased (+0.5%) to 98.999% when pulling 84218966160662dcb873938d243eef21e191f0db on hello-baby:support-unified-receipts into a61a68935c9aef8c0ac72e47b7b56c2451fb206f on jnbt:master.

zabolotnov87 commented 6 years ago

Hi, will you check it?