React-native-iap: فشل الشراء داخل التطبيق على iOS عند إضافة طريقة الدفع مباشرة عندما لا تكون هناك طريقة دفع موجودة بالفعل

تم إنشاؤها على ٣١ أكتوبر ٢٠١٨  ·  27تعليقات  ·  مصدر: dooboolab/react-native-iap

نسخة من رد فعل - أصلية - IAP

react-native-iap": "^2.3.17

المنصات التي واجهت الخطأ فيها (IOS أو Android أو كليهما؟)

iOS

سلوك متوقع

يجب أن يتم الدفع فقط عند استدعاء finishTransaction

السلوك الفعلي

يتم الكشف عن المبلغ بعد إضافة طريقة دفع مثل بطاقة الائتمان.
ولكن تم الوصول إلى طريقة RNIap.buyProductWithoutFinishTransaction(sku) .

بيئة اختبار (محاكي؟ جهاز حقيقي؟)

جهاز حقيقي - iPhone 6s

خطوات إعادة إنتاج السلوك

  • تحقق للتأكد من أن حساب Apple في الجهاز تم تعيين طريقة الدفع على لا شيء أو بعض تفاصيل الدفع غير الصالحة
  • قم بالشراء داخل التطبيق من خلال التطبيق
  • يتم نقل المستخدم إلى صفحة إعدادات الحساب لإضافة طريقة دفع صالحة
  • يتم تحصيل رسوم طريقة الدفع ولكن لم يتم استلام إيصال المعاملة في الكود المذكور أدناه
ComponentDidMount(){
     await RNIap.initConnection();
     await RNIap.consumeAllItems();
     const prod = await RNIap.getProducts(product);

} 

  async componentWillUnmount() {
       RNIap.endConnection()
}

buyProduct(sku){
await RNIap.clearTransaction();

RNIap.buyProductWithoutFinishTransaction(sku)
.then(purchase => {
  // not reached
 if(calltoserverisSuccess){
    RNIap.finishTransaction();
 }
})
.catch(error => {
 // code enters catch case if ever
}}
📱 iOS 🙏 help wanted

التعليق الأكثر فائدة

أعتقد أننا بحاجة إلى الاتصال بـ apple لهذا الغرض ، ويبدو هذا أمرًا مروعًا حقًا لوجود حالة اختبار مختلفة غير قابلة للتكرار في بيئة sandbox . بالنسبة لأولئك الذين يريدون فهم المشكلة ، قمت بتسجيل الشاشة ويمكنك مشاهدة المقطع هنا . anandwahed هل يمكنك أيضًا الاتصال

ال 27 كومينتر

آسف لقول هذا ولكن يبدو أن التعليمات البرمجية الخاصة بك بها العديد من الأخطاء في بناء الجملة. يرجى الرجوع إلى مثال مشروعنا في الريبو الخاص بنا والمقارنة مع الكود الخاص بك أولاً.

تضمين التغريدة
شكرًا على الرد ، الكود الذي تم نشره هنا هو فقط على سبيل المثال ، ليس هذا هو بالضبط الذي يتم استخدامه في التطبيق الحقيقي.
سأحاول شرح ما هي المشكلة

  1. المكون

    • بدأ الاتصال عن طريق استدعاء RNIap.initConnection();

    • ثم يتم جلب المنتجات وتخزينها في الحالة من خلال استدعاء RNIap.getProducts(product)

  1. عندما ينقر المستخدم على زر الشراء

    • يتم استدعاء RNIap.clearTransaction(); فقط للتأكد من عدم وجود معاملات معلقة متبقية.
    • يتم استدعاء RNIap.buyProductWithoutFinishTransaction(sku) في حالة نجاح استدعاء خادم التطبيق إذا قدم الخادم حالة نجاح صحيحة ، ثم يتم استدعاء RNIap.finishTransaction(); لإكمال الدفع.
  2. ComponentWillUnmount ()

    • RNIap.endConnection() لإنهاء الاتصال.

تعمل هذه العملية بشكل جيد إذا كان المستخدم قد أضاف بالفعل طريقة الدفع. عندما لا يكون المستخدم لديه طريقة دفع مضافة ، فسيتطلب الأمر إضافة صفحة طريقة الدفع ويتم تحصيل المبلغ قبل الوصول إلى RNIap.finishTransaction();

شكرا على التفاصيل. مشكلتك تبدو واضحة الآن. ccJJMoon

تضمين التغريدة

@ zohaibahmed-22 هل هذه حالة اختبار رمل؟

JJMoon لا ، إنها حالة بيئة حقيقية.

أتفهم أن هذا الخطأ يحدث عندما يكون المستخدم في حالة تسجيل الخروج ، أو عندما لا تكون لديه معلومات عن بطاقة الائتمان.
إذا كانت الطرق تعمل بشكل جيد ، فإن سبب هذا الخطأ يكمن في مكان آخر.
نحتاج إلى إعداد هذا الإجراء ، الذي يترك التطبيق ، viewDidDisappear وما إلى ذلك.
في وضع الحماية ، يحدث هذا العرض بطريقة مختلفة نوعًا ما.
عندما أقوم بإنشاء حساب Sandbox جديد ، ولا تنجح عملية الشراء الأولى.
في المرة الثانية ، يتم تسجيل دخول الجهاز ، ويعمل بشكل جيد.
ليس لدي دليل على هذا الخطأ.

dooboolab و @ JJMoon أيضًا أعتقد أنني وجدت المشكلة عند المعاملات المحدثة عندما نتلقى رسالة فشل في SKPaymentTransactionStateDeferred أو SKPaymentTransactionStateFailed لا نفترض أن finishTransaction .

نظرًا لأنه في كثير من الحالات ، تكون النتيجة SKPaymentTransactionStateFailed متبوعة بـ SKPaymentTransactionStatePurchased كما هو مذكور في الموضوع أعلاه 6431 . لست متأكدًا من رمز Objective-C ، لذا يرجى التحقق والتأكد مما إذا كنا قد مسحنا المعاملة عند الفشل.

anandwahed أوافقك الرأي . هذا خطأي. اسف على ذلك.
سوف ألقي نظرة على خيط Apple وأعتني بالمسألة.

anandwahed أعتقد أنه الطريق الصحيح إلى finish transaction عندما يفشل. الرجاء البحث عن هذا الموضوع. https://stackoverflow.com/questions/11008636/inapp-purchase-skpaymentqueue-finish-transaction-doesnt-work
عندما تفشل ، لن يكون هناك إيصال ، لذلك لا تطبق منتج الشراء. ولا تعني الصفقة النهائية دائمًا "شراء".
في غضون ذلك ، سأبحث في الموضوع 6431.

لقد قرأت للتو الخيط 6431 (https://forums.developer.apple.com/thread/6431#14562)
الخط السفلي. المشكلة لم تحل منذ 2015. واو ..
هناك طريقتان مختلفتان للتعامل مع تأثير "تدفق مجموعة المتجر".

  1. لا تظهر أي تنبيه المستخدم.
  2. اعرض النتيجة.

وتعلمت شيئين.
A. علينا أن finishTransaction عندما فشل. (أعتقد دائمًا بوجود خيار أو بدونه)
B. تدفق Storekit يجعل الفشل والنجاح مع الاستلام على حد سواء. (هذا سيء)

أقترح عليكم جميعًا قراءة هذا الموضوع والعودة إلى هذا الموضوع.

أعتقد ، بالطريقة التي تختارها (1 أو 2) ، إنها بمفردك.
قد نحتاج إلى معاودة الاتصال للاستجابة للفشل.

JJMoon هل يعني ذلك أنه لا يجب استخدام buyProductWithoutFinishTransaction؟

@ maxs15 لم أقصد ذلك. آسف للتشويش.
يمكن أن يحدث تدفق StoreKit في أي عملية شراء. إنها مشكلة iOS ، وليس هذه الوحدة.
في الوقت الحالي ، ليس لدي أي دليل أيضًا. يحدث هذا الشيء في أي تطبيقات iOS أصلية. حق؟
سنحفر أكثر في وقت فراغنا.

اليوم ، حاولت تصحيح هذه المشكلة لأنني ولدت هذه المشكلة. الدفعة finishTransanction واكتملت ولكن لم يتم الحصول على callback عند تغيير payMethod. لقد حاولت تصحيح أخطاء كتابة بعض console.log لكنني لم أتمكن من اختبار الفوترة الحقيقية في بيئة dev . هل يمكن لأي شخص أن يقترح علي كيفية تصحيح هذه العملية حتى يمكنني debug هذا مقابل real purchase ؟ هل يجب علي استخدام هذا في وضع sandbox ؟ إنه يعمل بشكل مثالي في وضع الحماية لذلك ليس لدي أي فكرة عن كيفية تصحيح هذا. هذا متردد جدا.

دعنا نجمع بعض الأفكار لأنني أعتقد أن هذا مهم جدًا ليتم إصلاحه.

أتلقى هذا الخطأ دائمًا عندما أحاول الشراء مع مستخدم ليس في وضع الحماية.

hyochan إذا قمت بتوصيل الخادم الحقيقي (الخاص بك) ، سواء كنت في وضع التصحيح أو وضع الإصدار لا يهم. أعتقد أن لديك خياران.

  1. تقوم بتشغيل الجهاز الحقيقي في وضع التصحيح في Xcode. استخدم سجل وحدة التحكم JS.
  2. يتم التشغيل على الجهاز الحقيقي في وضع الإصدار في Xcode. استخدم NSLog في كود الهدف c.
    كلتا الطريقتين يجب أن تعمل.

JJMoon نعم ، لقد اكتشفت ذلك بالفعل ولكن ما زلت لا أستطيع إجراء اختبار شراء مباشر في iOS. هل هذا التدفق التراكمي صحيح؟ إذن كيف يمكنني حل هذه المشكلة؟ علينا اختبار الشراء الحي.

أي شخص يواجه هذه المشكلة ، أنا متأكد من أنهم جميعًا يواجهون هذه المشكلة ، يرجى إعطائنا فكرة عن كيفية مواجهة هذه المشكلة. in-app purchase fail when payment method added live كما هو موضح في عنوان الإصدار. كيف يمكنني تصحيح هذا؟ anandwahed هل سبق لك أن

hyochan لا ، لم نتصل بدعم Apple.

أعتقد أننا بحاجة إلى الاتصال بـ apple لهذا الغرض ، ويبدو هذا أمرًا مروعًا حقًا لوجود حالة اختبار مختلفة غير قابلة للتكرار في بيئة sandbox . بالنسبة لأولئك الذين يريدون فهم المشكلة ، قمت بتسجيل الشاشة ويمكنك مشاهدة المقطع هنا . anandwahed هل يمكنك أيضًا الاتصال

اليوم تلقينا إجابة من Apple. قد يتم إرجاع رد الاتصال مرة أخرى بعد failure . نحن نعمل على حل بديل في رقم 348 لكنني أخشى أن يكون هذا سيئًا للغاية.

لقد قمت بالتحرير إلى 2.4.0-beta1 ، في محاولة لعمل حل بديل لهذه المشكلة. تمت إضافة PR # 348 إلى هذا الإصدار ويمكنك أيضًا مشاهدة الملف التمهيدي لهذه الميزة . لاحظ أن هذا قيد الاختبار.

لقد اختبرت هذا في عملية شراء مباشرة ويبدو أنها تعمل. ومع ذلك ، ضع في اعتبارك أنه يجب عليك إضافة مستمع فقط عندما يكون هناك فشل أو قد يتكرر مع نتيجة ناجحة.

شكرا لكم يا رفاق على استثمار الوقت في هذه المشكلة! 🙏

أعتقد أن الوثائق الحالية يجب أن تكون أكثر وضوحًا حول استخدام addAdditionalSuccessPurchaseListenerIOS . هذا شيء حاولت معالجته في # 414.

لكنني أعتقد أيضًا أن هذا يترك مجالًا لتحسين واجهة برمجة التطبيقات. هل ستكونون منفتحين على مناقشة تغيير في واجهة برمجة التطبيقات يمكن أن تستوعب بشكل أفضل ما يسمى "تدفق مجموعة المتجر"؟ شيء ما ربما يستخدم RxJS ، على سبيل المثال:

const observable = RNIap.buyProduct('com.example.coins100')
                        .subscribe(
                            purchase => console.log(purchase), // successful payment
                            err => console.log(err) // err.code and err.message are available
                        )

أو شيء مختلف يخفي بشكل أفضل الاشتراك الإضافي لنظام iOS؟

Edgpaez هذا رائع ولكن هذا سيغير سلوك الشراء الذي يتم في android . آمل أن أتمكن من التحقيق في version 3 لهذه الوحدة في 2019 .

مرحبًا hyochan ، AFAICT ، لسنا بحاجة إلى تغيير السلوك الداخلي للحزمة ، فقط الواجهة العامة. يمكننا الحفاظ على طريقة buyItemByType لحل الوعود وإضافة القليل من Rx فوق ذلك على index.js .

على سبيل المثال ، لدينا هذا في index.js:

export const buyProduct = (sku) => Platform.select({
  android: () => Observable.of(RNIapModule.buyItemByType(ANDROID_ITEM_TYPE_IAP, sku, null, 0)), // returns an observable that emits when the RNIapModule.buyItemByType promise resolves
  ios: ... // ios would do the same but taking into account the usage of addAdditionalSuccessPurchaseListenerIOS
})();

لا يتمثل هدفي في هذا التنفيذ المحدد ولكن إخفاء التفاصيل الخاصة بـ "تدفق مجموعة أدوات التخزين".
هل تعتقد بان هذه فكرة رائعة؟
هل أنت مهتم بالعلاقات العامة؟

Edgpaez طيب. أنا أفهم التفاصيل الآن. ومع ذلك ، أشعر أن إضافة RxJS أكثر من اللازم بالنسبة لتطبيق feature لأنني أعتقد أنه يمكن تغطيته بدونه.

أيضًا ، أشعر أن ما يلي سيكون شيئًا مختلفًا.

RNIap.buyProduct('com.example.coins100')
                        .subscribe(
                            purchase => console.log(purchase), // successful payment
                            err => console.log(err) // err.code and err.message are available
                        )

إذا اتصلت بـ buyProduct لعنصرين مثل أدناه ،

RNIap.buyProduct('com.example.coins100');
RNIap.buyProduct('com.example.coins200');

لا يمكننا ضمان أي واحد سينتهي أولاً ، لذا أعتقد أننا يجب أن نتعامل مع هذا في الأصل إلى sendEvent إلى JS .

أشعر أن التنفيذ يجب أن يبدو

RNIap.buyProduct('com.example.coins100');
RNIap.buyProduct('com.example.coins200');

// receiving events
const subs =  RNIap.purchaseUpdateListener(purchase => {
  ...
});

من فضلك قل لي إذا كان هناك شيء فاتني.

دعنا نتعامل مع مزيد من disccustin في # 423

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات